Vă mulțumim pentru susținere

Cum se utilizează API-ul socket C în C ++ pe z / OS

Am avut probleme în a obține API-ul pentru socket-uri C pentru a funcționa corect în C ++. În mod specific, deși includ sys / socket.h , încă mai obțin erori de timp de compilare, spunându-mi că AF_INET nu este definită. Am pierdut ceva evident, sau ar putea fi legat de faptul că fac codificarea pe z / OS și problemele mele sunt mult mai complicate?


Update: Upon further investigation, I discovered that there is an #ifdef that I'm hitting. Apparently z/OS isn't happy unless I define which "type" of sockets I'm using with:

#define _OE_SOCKETS

Acum, eu personal nu am nici o idee despre ce este de fapt _OE_SOCKETS , deci dacă vreun programator z / OS este acolo (toți 3 dintre voi), poate ați putea da mi-o treabă cum funcționează toate acestea?


Sigur că pot posta o aplicație de testare.

#include 

int main()
{
    return AF_INET;
}

Compilație / ieșire link:

cxx -Wc, xplink -Wl, xplink -o inet_test inet.C

"./inet.C", linia 5.16: CCN5274 (S) Căutarea numelui pentru "AF_INET" nu a găsit o declarație.

CCN0797 (I) Compilarea a eșuat pentru fișierul ./inet.C. Fișierul obiect nu a fost creat.

O verificare a sys / sockets.h include definiția de care am nevoie și, în măsura în care pot spune, nu este blocată de nicio declarație #ifdef.

Am observat totuși că conține următoarele:

#ifdef __cplusplus
  extern "C" {
#endif

care încapsulează în esență întregul dosar. Nu e sigur dacă contează.

0
adăugat editat

9 răspunsuri

Nu am avut probleme cu utilizarea API-ului BSD socket-uri în C ++, în GNU / Linux. Iată programul de probă pe care l-am folosit:

#include 

int
main()
{
    return AF_INET;
}

Deci, să iau acest lucru este faptul că z / OS este probabil factorul complicator aici, totuși, pentru că nu am folosit niciodată z / OS înainte, mult mai puțin programat în el, nu pot spune acest lucru definitiv. :-P

0
adăugat

@Jax: Cheia extern "C" contează, foarte mult. Dacă un fișier de antet nu are unul, atunci (cu excepția cazului în care este un fișier de antet numai pentru C ++), va trebui să includeți codul dvs. #include cu acesta:

extern "C" {
#include 
// include other similarly non-compliant header files
}

Basically, anytime where a C++ program wants to link to C-based facilities, the extern "C" is vital. In practical terms, it means that the names used in external references will not be mangled, like normal C++ names would. Reference.

0
adăugat

Vedeți secțiunea Utilizarea z / OS UNIX System Services sockets din Ghidul de programare z / OS XL C / C ++. Asigurați-vă că includeți fișierele antet necesare și utilizând #defines corespunzătoare.

The link to the doc has changed over the years, but you should be able to get to it easily enough by finding the current location of the Support & Downloads section on ibm.com and searching the documentation by title.

0
adăugat

Așa că încercați

#define _OE_SOCKETS

înainte de a include sys / socket.h

0
adăugat

Modul _OE_SOCKETS pare a fi doar pentru a activa / dezactiva definiția simbolurilor legate de soclu. Nu este ceva neobișnuit în unele biblioteci să aibă o grămadă de macro-uri pentru a face acest lucru, pentru a vă asigura că nu compilați / conectați părți care nu sunt necesare. Macro nu este standard în alte implementări socket, pare să fie ceva specific pentru z / OS.

Take a look at this page:
Compiling and Linking a z/VM C Sockets Program

0
adăugat
z / OS are la fel de multe în comun cu z / VM ca Windows face cu Linux, așa că eu sunt un pic cam confuz de ce ați postat această legătură.
adăugat autor paxdiablo
Observați că macroul _OE_SOCKETS apare în ambele și pare să aibă același scop. Ceea ce nu este surprinzător, deoarece probabil IBM folosea aceeași bază de cod pentru suportul pentru socket-uri în ambele produse. Nu am intenția să spun că documentația z / VM se aplică z / OS, este doar cazul cel mai asemănător pe care l-am găsit.
adăugat autor Fabio Ceconello
Cred că e doar o coincidență. z / VM nu utilizează produsul z / OS Language Environment, care furnizează fișierele antet relevante folosite pentru a efectua apeluri socket.
adăugat autor Anthony Giorgio

DISCLAIMER: Nu sunt un programator C ++, cu toate astea stiu C foarte bine. eu a adaptat aceste apeluri din unele coduri C pe care le am.

Also markdown put these strange _ as my underscores.

Ar trebui doar să puteți scrie o clasă de abstractizare în jurul prizelor C cu ceva de genul:

class my_sock {
    private int sock;
    private int socket_type;
    private socklen_t sock_len;
    private struct sockaddr_in server_addr;
    public char *server_ip;
    public unsigned short server_port;
};

Apoi, aveți metode pentru deschiderea, închiderea și trimiterea pachetelor în jos.

De exemplu, apelul deschis ar putea arăta astfel:

int my_socket_connect()
{
    int return_code = 0;

    if ( this->socket_type != CLIENT_SOCK ) {
        cout << "This is a not a client socket!\n";
        return -1;
    }

    return_code = connect( this->local_sock, (struct sockaddr *) &this->server_addr, sizeof(this->server_addr));

    if( return_code < 0 ) {
        cout << "Connect() failure! %s\n", strerror(errno);
        return return_code;
    }

    return return_code;
}
0
adăugat
Acest lucru nu are nimic de-a face cu întrebarea inițială.
adăugat autor Anthony Giorgio

Poate doriți să aruncați o privire la cpp-sockets , un C ++ wrapper pentru apelurile sistemelor socket . Funcționează cu multe sisteme de operare (Win32, POSIX, Linux, * BSD). Nu cred că va funcționa cu z / OS, dar puteți să aruncați o privire la fișierele pe care le utilizează și veți avea multe exemple de cod testat care funcționează bine pe alte sisteme de operare.

0
adăugat

Păstrați o copie a manualelor IBM la îndemână:

Publicațiile IBM sunt, în general, foarte bune, dar trebuie să vă obișnuiți cu FORMATul acestora, precum și să știți unde să căutați un răspuns. Veți găsi destul de des că o caracteristică pe care doriți să o utilizați este păzită de o "macro de testare a caracteristicilor"

Ar trebui să cereți programatorului dvs. prietenos să instalați XL C / Recomandare Bibliotecă C ++ de run-time: pagini de om pe sistemul dvs. Apoi puteți face lucruri precum "conectați omul" pentru a extrage pagina man pentru API-ul socket connect (). Când fac asta, asta văd:

FORMAT

X / Open

#define _XOPEN_SOURCE_EXTENDED 1
#include 

int connect(int socket, const struct sockaddr *address, socklen_t address_len);

Berkeley Sockets

#define _OE_SOCKETS
#include 
#include 

int connect(int socket, struct sockaddr *address, int address_len);
0
adăugat

Răspunsul este utilizarea pavilionului c89 care urmează:

 -D_OE_SOCKETS

Exemplul urmează;

 bash-2.03$ c89 -D_OE_SOCKETS [filename].c

Pentru mai multe informații, căutați opțiunile C89 din Ghidul utilizatorului z / OS XLC / C ++.

0
adăugat