Verwendung der C-Socket-API in C ++ unter z / OS


157

Ich habe Probleme der C - Sockets API an die Arbeit richtig in C++auf z/OS.

Obwohl ich einschließe sys/socket.h, erhalte ich immer noch Fehler bei der Kompilierung, die mir mitteilen, dass dies AF_INETnicht definiert ist .

Vermisse ich etwas Offensichtliches oder hängt dies damit zusammen, dass z/OSmeine Probleme viel komplizierter werden?


Update : Bei weiteren Untersuchungen stellte ich fest, dass es eine gibt #ifdef, die ich treffe. Anscheinend z/OSist es nicht glücklich, wenn ich nicht definiere, mit welchem ​​"Typ" von Steckdosen ich arbeite:

#define _OE_SOCKETS

Nun, ich persönlich habe keine Ahnung, wofür das _OE_SOCKETSeigentlich ist. Wenn also z/OSSockets-Programmierer da draußen sind (Sie alle drei), könnten Sie mir vielleicht einen Überblick darüber geben, wie das alles funktioniert?


Test App

#include <sys/socket.h>

int main()
{
    return AF_INET;
}

Ausgabe kompilieren / verknüpfen:

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.

Eine Überprüfung von sys / sockets.h enthält die Definition, die ich benötige, und soweit ich das beurteilen kann, wird sie nicht durch #ifdefAnweisungen blockiert .

Ich habe jedoch bemerkt, dass es Folgendes enthält:

#ifdef __cplusplus
  extern "C" {
#endif

Was kapselt im Grunde die gesamte Datei? Ich bin mir nicht sicher, ob es darauf ankommt.

Antworten:


86

Halten Sie eine Kopie der IBM Handbücher bereit:

Die IBM Veröffentlichungen sind im Allgemeinen sehr gut, aber Sie müssen sich an ihr Format gewöhnen und wissen, wo Sie nach einer Antwort suchen müssen. Sie werden häufig feststellen, dass eine Funktion, die Sie verwenden möchten, durch ein "Feature-Test-Makro" geschützt wird.

Sie sollten Ihren freundlichen Systemprogrammierer bitten, die XL C / C ++ - Laufzeitbibliotheksreferenz: Man Pages auf Ihrem System zu installieren. Anschließend können Sie beispielsweise "man connect" ausführen, um die Manpage für die Socket connect () -API aufzurufen. Wenn ich das mache, sehe ich Folgendes:

FORMAT

X / Öffnen

#define _XOPEN_SOURCE_EXTENDED 1
#include <sys/socket.h>

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

Berkeley-Steckdosen

#define _OE_SOCKETS
#include <sys/types.h>
#include <sys/socket.h>

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

38

Ich hatte keine Probleme mit der Verwendung der BSD-Sockets-API in C ++ unter GNU / Linux. Hier ist das Beispielprogramm, das ich verwendet habe:

#include <sys/socket.h>

int
main()
{
    return AF_INET;
}

Ich gehe davon aus, dass z / OS hier wahrscheinlich der komplizierende Faktor ist, da ich z / OS noch nie zuvor verwendet habe, geschweige denn darin programmiert, kann ich dies nicht definitiv sagen. :-P


32

Siehe die Sockets Verwenden von z / OS UNIX-Systemdiensten Abschnitt im z / OS XL C / C ++ - Programmierhandbuch. Stellen Sie sicher, dass Sie die erforderlichen Header-Dateien einschließen und die entsprechenden #defines verwenden.

Der Link zum Dokument hat sich im Laufe der Jahre geändert. Sie sollten jedoch in der Lage sein, leicht darauf zuzugreifen , indem Sie den aktuellen Speicherort des Abschnitts Support & Downloads auf ibm.com suchen und die Dokumentation nach Titel durchsuchen.


26

Das _OE_SOCKETS scheint einfach zu sein, um die Definition von Socket-bezogenen Symbolen zu aktivieren / deaktivieren. In einigen Bibliotheken ist es nicht ungewöhnlich, dass eine Reihe von Makros vorhanden sind, um sicherzustellen, dass Sie keine nicht benötigten Teile kompilieren / verknüpfen. Das Makro ist in anderen Socket-Implementierungen nicht Standard, es scheint etwas Spezifisches für z / OS zu sein.

Schauen Sie sich diese Seite an:
Kompilieren und Verknüpfen des az / VM C-Sockets-Programms


2
z / OS hat mit z / VM genauso viel gemeinsam wie Windows mit Linux, daher bin ich ein wenig amüsiert, warum Sie diesen Link gepostet haben.
Paxdiablo

Beachten Sie, dass das Makro _OE_SOCKETS in beiden angezeigt wird und denselben Zweck zu haben scheint. Dies ist nicht überraschend, da IBM wahrscheinlich in beiden Produkten dieselbe Codebasis für die Socket-Unterstützung verwendet hat. Ich wollte nicht sagen, dass die z / VM-Dokumentation für z / OS gilt, es ist nur der ähnlichste Fall, den ich gefunden habe.
Fabio Ceconello

1
Ich denke, es ist nur ein Zufall. z / VM verwendet nicht das Produkt z / OS Language Environment, das die relevanten Header-Dateien enthält, die für Socket-Aufrufe verwendet werden.
Anthony Giorgio

25

Also versuche

#define _OE_SOCKETS

bevor Sie sys / socket.h einschließen


19

Vielleicht möchten Sie einen Blick auf cpp-sockets werfen , einen C ++ - Wrapper für die Sockets-Systemaufrufe. Es funktioniert mit vielen Betriebssystemen (Win32, POSIX, Linux, * BSD). Ich glaube nicht, dass es mit z / OS funktioniert, aber Sie können sich die verwendeten Include-Dateien ansehen und Sie werden viele Beispiele für getesteten Code haben, der auf anderen Betriebssystemen gut funktioniert.


18

@Jax: Die extern "C"Sache ist sehr wichtig. Wenn eine Header-Datei keine hat, müssen Sie (es sei denn, es handelt sich um eine C ++ - nur Header-Datei) Ihre folgende Datei beifügen #include:

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

Grundsätzlich ist dies immer dann von entscheidender Bedeutung, wenn ein C ++ - Programm eine Verbindung zu C-basierten Einrichtungen herstellen möchte extern "C". In der Praxis bedeutet dies, dass die in externen Referenzen verwendeten Namen nicht wie normale C ++ - Namen entstellt werden. Referenz.


14

HAFTUNGSAUSSCHLUSS: Ich bin kein C ++ - Programmierer, aber ich kenne C sehr gut. Ich habe diese Aufrufe von einem C-Code angepasst, den ich habe.

Auch Markdown setzen diese seltsamen _ als meine Unterstriche.

Sie sollten nur in der Lage sein, eine Abstraktionsklasse um die C-Sockets zu schreiben:

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

Dann haben Sie Methoden zum Öffnen, Schließen und Senden von Paketen über den Socket.

Zum Beispiel könnte der offene Anruf ungefähr so ​​aussehen:

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

Dies hat nichts mit der ursprünglichen Frage zu tun.
Anthony Giorgio

13

Die Antwort lautet: Verwenden Sie das folgende c89-Flag:

 -D_OE_SOCKETS

Beispiel folgt;

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

Weitere Informationen finden Sie im z / OS XLC / C ++ - Benutzerhandbuch unter C89-Optionen.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.