Comment utiliser l'API de socket C en C ++ sur z / OS

Translate

Je rencontre des problèmes pour que l'API C sockets fonctionne correctement en C ++ surz/OS.

Bien que j'inclussys/socket.h, Je reçois toujours des erreurs de compilation me disant queAF_INETn'est pas défini.

Est-ce que je manque quelque chose d'évident, ou est-ce lié au fait quez/OSrend mes problèmes beaucoup plus compliqués?


Mettre à jour: Après une enquête plus approfondie, j'ai découvert qu'il y avait un#ifdefque je frappe. Apparemmentz/OSn'est pas content à moins que je ne définisse avec quel "type" de sockets j'utilise:

#define _OE_SOCKETS

Maintenant, je n'ai personnellement aucune idée de ce que c'est_OE_SOCKETSest en fait pour, donc le cas échéantz/OSles programmeurs de sockets sont là-bas (tous les 3), peut-être pourriez-vous me donner un aperçu de la façon dont tout cela fonctionne?


Tester l'application

#include <sys/socket.h>

int main()
{
    return AF_INET;
}

Compiler / Lier la sortie:

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.

Une vérification de sys / sockets.h inclut la définition dont j'ai besoin, et pour autant que je sache, elle n'est bloquée par aucune instruction #ifdef.

J'ai cependant remarqué qu'il contient les éléments suivants:

#ifdef __cplusplus
  extern "C" {
#endif

qui encapsule essentiellement le fichier entier. Je ne sais pas si cela compte.

This question and all comments follow the "Attribution Required."

Toutes les réponses

Translate

Gardez une copie des manuels IBM à portée de main:

Les publications IBM sont généralement très bonnes, mais il faut s'habituer à leur format et savoir où chercher une réponse. Vous constaterez assez souvent qu'une fonctionnalité que vous souhaitez utiliser est protégée par une "macro de test de fonctionnalité"

Vous devriez demander à votre programmeur système convivial d'installer leRéférence de la bibliothèque d'exécution XL C / C ++: pages de manuelsur votre système. Ensuite, vous pouvez faire des choses comme "man connect" pour afficher la page de manuel de l'API socket connect (). Quand je fais cela, voici ce que je vois:

FORMAT

X / Ouvrir

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

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

Douilles Berkeley

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

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

Je n'ai eu aucun problème à utiliser l'API des sockets BSD en C ++, sous GNU / Linux. Voici l'exemple de programme que j'ai utilisé:

#include <sys/socket.h>

int
main()
{
    return AF_INET;
}

Donc, mon point de vue à ce sujet est que z / OS est probablement le facteur de complication ici, cependant, parce que je n'ai jamais utilisé z / OS auparavant, et encore moins programmé dedans, je ne peux pas le dire définitivement. :-P

La source
Translate

Voir leUtilisation des sockets z / OS UNIX System Servicesdans le Guide de programmation de z / OS XL C / C ++. Assurez-vous d'inclure les fichiers d'en-tête nécessaires et d'utiliser les #defines appropriées.

Le lien vers le document a changé au fil des ans, mais vous devriez pouvoir y accéder assez facilement en trouvant l'emplacement actuel duSection support et téléchargementssuribm.comet la recherche de la documentation par titre.

La source
Translate

Alors essayez

#define _OE_SOCKETS

avant d'inclure sys / socket.h

La source
Translate

Le _OE_SOCKETS semble être simplement pour activer / désactiver la définition des symboles liés aux sockets. Il n'est pas rare dans certaines bibliothèques d'avoir un tas de macros pour faire cela, pour s'assurer que vous ne compilez pas / reliez des parties inutiles. La macro n'est pas standard dans d'autres implémentations de sockets, elle semble être quelque chose de spécifique à z / OS.

Jetez un œil à cette page:
Compilation et liaison du programme de sockets z / VM C

La source
Translate

Vous voudrez peut-être jeter un oeil àcpp-sockets, un wrapper C ++ pour les appels système des sockets. Il fonctionne avec de nombreux systèmes d'exploitation (Win32, POSIX, Linux, * BSD). Je ne pense pas que cela fonctionnera avec z / OS, mais vous pouvez jeter un œil aux fichiers d'inclusion qu'il utilise et vous aurez de nombreux exemples de code testé qui fonctionne bien sur d'autres systèmes d'exploitation.

La source
Translate

@Jax: Leextern "C"la chose compte, très beaucoup. Si un fichier d'en-tête n'en a pas, alors (à moins qu'il ne s'agisse d'un fichier d'en-tête uniquement C ++), vous devrez inclure votre#includeavec ça:

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

Fondamentalement, chaque fois qu'un programme C ++ souhaite se lier à des installations basées sur C, leextern "C"c'est essentiel. En termes pratiques, cela signifie que les noms utilisés dans les références externes ne seront pas mutilés, comme le feraient les noms C ++ normaux.Référence.

La source
Translate

AVERTISSEMENT: Je ne suis pas un programmeur C ++, mais je connais très bien le C. J'ai adapté ces appels à partir de certains codes C que j'ai.

Markdown a également mis ces étranges _ comme soulignements.

Vous devriez simplement être capable d'écrire une classe d'abstraction autour des sockets C avec quelque chose comme ceci:

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

Ensuite, avez des méthodes pour ouvrir, fermer et envoyer des paquets dans le socket.

Par exemple, l'appel ouvert peut ressembler à ceci:

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;
}
La source
Translate

La réponse est d'utiliser l'indicateur c89 qui suit:

 -D_OE_SOCKETS

L'exemple suit;

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

Pour plus d'informations, recherchez les options C89 dans le Guide de l'utilisateur z / OS XLC / C ++.

La source