De C-socket API gebruiken in C++ op z/OS

Ik heb problemen om de C sockets API correct te laten werken in C++ op z/OS.

Hoewel ik sys/socket.hgebruik, krijg ik nog steeds fouten tijdens het compileren die me vertellen dat AF_INETniet is gedefinieerd.

Mis ik iets voor de hand liggends, of heeft dit te maken met het feit dat het gebruik van z/OS mijn problemen veel gecompliceerder maakt?

Ik ontdekte dat er een #ifdefis die ik aanraak. Blijkbaar is z/OS niet tevreden, tenzij ik definieer met welk “type” sockets ik gebruik:

#define _OE_SOCKETS

Ik heb persoonlijk geen idee waar deze _OE_SOCKETSeigenlijk voor is, dus als er z/OS sockets-programmeurs zijn (jullie alle drie), kun je me misschien een overzicht geven van hoe werkt dit allemaal?

App testen

#include <sys/socket.h>
int main()
{
    return AF_INET;
}

Uitvoer compileren/linken:

cxx -Wc,xplink -Wl,xplink -o inet_test inet.C
"./inet.C", line 5.16: CCN5274 (S) The name lookup for "AF_INET" did not find a declaration.
CCN0797(I) Compilation failed for file ./inet.C. Object file not created.

Een controle van sys/sockets.h bevat de definitie die ik nodig heb, en voor zover ik weet, wordt deze niet geblokkeerd door #ifdef-statements.

Ik heb echter gemerkt dat het het volgende bevat:

#ifdef __cplusplus
  extern "C" {
#endif

die in feite het hele bestand inkapselt? Ik weet niet zeker of het ertoe doet.


Antwoord 1, autoriteit 100%

Houd een kopie van de IBM-handleidingen bij de hand:

De IBM-publicaties zijn over het algemeen erg goed, maar je moet aan hun formaat wennen en weten waar je het antwoord moet zoeken. U zult vaak merken dat een functie die u wilt gebruiken, wordt bewaakt door een “functietestmacro”

Vraag je vriendelijke systeemprogrammeur om de te installeren XL C/C++ Runtime Bibliotheek Referentie: Man Pages
op uw systeem. Dan kun je dingen doen als “man connect” om de man-pagina voor de socket connect() API op te halen. Als ik dat doe, zie ik dit:

FORMAAT

X/Open

#define _XOPEN_SOURCE_EXTENDED 1
#include <sys/socket.h>
int connect(int socket, const struct sockaddr *address, socklen_t address_len);

Berkeley-contactdozen

#define _OE_SOCKETS
#include <sys/types.h>
#include <sys/socket.h>
int connect(int socket, struct sockaddr *address, int address_len);

Antwoord 2, autoriteit 46%

Ik heb geen problemen gehad met het gebruik van de BSD sockets API in C++, in GNU/Linux. Dit is het voorbeeldprogramma dat ik heb gebruikt:

#include <sys/socket.h>
int
main()
{
    return AF_INET;
}

Dus mijn mening hierover is dat z/OS hier waarschijnlijk de complicerende factor is, maar omdat ik z/OS nog nooit eerder heb gebruikt, laat staan ​​erin geprogrammeerd, kan ik dit niet definitief zeggen. 😛


Antwoord 3, autoriteit 40%

Zie het gedeelte Z/OS UNIX System Services-sockets gebruikenin de z/OS XL C/C++ Programming Guide. Zorg ervoor dat u de benodigde header-bestanden opneemt en de juiste #defines gebruikt.

De link naar het document is in de loop der jaren veranderd, maar u zou er gemakkelijk genoeg moeten kunnen komen door de huidige locatie van de Ondersteuning & Sectie Downloadsop ibm.comen zoeken in de documentatie op titel.


Antwoord 4, autoriteit 33%

Probeer het dus

#define _OE_SOCKETS

voordat u sys/socket.h opneemt


Antwoord 5, autoriteit 33%

De _OE_SOCKETS lijkt eenvoudig te zijn om de definitie van socket-gerelateerde symbolen in of uit te schakelen. Het is in sommige bibliotheken niet ongebruikelijk om een ​​heleboel macro’s te hebben om dat te doen, om er zeker van te zijn dat je geen onderdelen compileert/linkt die niet nodig zijn. De macro is niet standaard in andere sockets-implementaties, het lijkt iets specifieks te zijn voor z/OS.

Bekijk deze pagina:
Het az/VM C Sockets-programma compileren en koppelen


Antwoord 6, autoriteit 25%

@Jax: Het extern "C"ding is heel erg belangrijk. Als een headerbestand er geen heeft (tenzij het een headerbestand is dat alleen in C++ is), moet u uw #includeerbij voegen:

extern "C" {
#include <sys/socket.h>
// include other similarly non-compliant header files
}

In principe is de extern "C"van vitaal belang wanneer een C++-programma een koppeling wil maken met op C gebaseerde faciliteiten. In praktische termen betekent dit dat de namen die in externe verwijzingen worden gebruikt, niet worden verminkt, zoals normale C++-namen zouden doen. Referentie.


Antwoord 7, autoriteit 25%

Misschien wil je eens kijken naar cpp-sockets, een C++-wrapper voor de sockets systeem oproepen. Het werkt met veel besturingssystemen (Win32, POSIX, Linux, *BSD). Ik denk niet dat het zal werken met z/OS, maar je kunt eens kijken naar de include-bestanden die het gebruikt en je zult veel voorbeelden hebben van geteste code die goed werkt op andere besturingssystemen.


Antwoord 8, autoriteit 20%

DISCLAIMER: ik ben geen C++ programmeur, maar ik ken C heel goed. l
heb deze oproepen aangepast met een C-code die ik heb.

Zet deze vreemde _ ook als mijn onderstrepingstekens.

Je zou gewoon een abstractieklasse rond de C-sockets moeten kunnen schrijven met zoiets als dit:

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;
};

Beschik dan over methoden voor het openen, sluiten en verzenden van pakketten door de socket.

Het open gesprek kan er bijvoorbeeld ongeveer zo uitzien:

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;
}

Antwoord 9, autoriteit 19%

Gebruik de volgende c89-vlag:

-D_OE_SOCKETS

Voorbeeld:

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

Zoek voor meer informatie naar c89-opties in de z/OS XLC/C++ Gebruikershandleiding.

Other episodes