Comment utiliser l’API socket C dans C ++ sous z / OS

J’ai des problèmes pour que l’API des sockets C fonctionne correctement en C ++ sous z/OS .

Bien que AF_INET sys/socket.h , je reçois toujours des erreurs de compilation en me disant que AF_INET n’est pas défini.

Suis-je en train de rater quelque chose d’évident ou est-ce lié au fait que sous z/OS complique beaucoup mes problèmes?


Mise à jour : Après une enquête plus approfondie, j’ai découvert qu’il y avait un #ifdef que je frappe. Apparemment, z/OS n’est pas content à moins de définir quel type de socket j’utilise avec:

 #define _OE_SOCKETS 

Maintenant, personnellement, je ne sais pas du tout à quoi _OE_SOCKETS ce _OE_SOCKETS , alors si des programmeurs de sockets z/OS sont présents (tous les trois), vous pourriez peut-être me décrire comment cela fonctionne?


App test

 #include  int main() { return AF_INET; } 

Comstackr / Link Output:

 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.

Conservez une copie des manuels IBM à scope de main:

  • Guide de programmation z / OS V1R11.0 XL C / C ++
  • Référence de la bibliothèque d’exécution z / OS V1R11.0 XL C / C ++

Les publications IBM sont généralement très bonnes, mais vous devez vous familiariser avec leur format et savoir où chercher une réponse. Vous trouverez très souvent qu’une fonctionnalité que vous souhaitez utiliser est protégée par une “macro de test de fonctionnalité”

Vous devriez demander à votre programmeur de système amical d’installer la référence de bibliothèque d’exécution XL C / C ++: Man Pages sur 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 ça, c’est ce que je vois:

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

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

 #include  int main() { return AF_INET; } 

Donc, mon sharepoint vue est que z / OS est probablement le facteur de complication ici, cependant, comme je n’ai jamais utilisé z / OS auparavant, et encore moins programmé, je ne peux pas le dire définitivement. 😛

Reportez-vous à la section Utilisation des sockets z / OS UNIX System Services du 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és.

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 de la section Support et téléchargements sur ibm.com et en recherchant la documentation par titre.

Alors essayez

 #define _OE_SOCKETS 

avant d’inclure sys / socket.h

Le _OE_SOCKETS semble être simplement pour activer / désactiver la définition des symboles liés au socket. Il n’est pas rare dans certaines bibliothèques d’avoir un tas de macros pour faire cela, afin de s’assurer que vous ne comstackz pas / ne liez pas les pièces dont vous n’avez pas besoin. La macro n’est pas standard dans les autres implémentations de sockets, elle semble être spécifique à z / OS.

Regardez cette page:
Compilation et liaison d’un programme de sockets z / VM C

Vous voudrez peut-être jeter un oeil à cpp-sockets , un wrapper C ++ pour les appels système de 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 oeil sur les fichiers inclus qu’il utilise et vous aurez de nombreux exemples de code testé qui fonctionne bien sur d’autres systèmes d’exploitation.

@Jax: La chose extern "C" est très importante. Si un fichier d’en-tête n’en a pas, alors (sauf s’il s’agit d’un fichier d’en-tête C ++ uniquement), vous devez joindre votre #include avec:

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

Fondamentalement, chaque fois qu’un programme C ++ veut établir un lien avec des installations basées sur C, le extern "C" est vital. En termes pratiques, cela signifie que les noms utilisés dans les références externes ne seront pas altérés, comme le feraient les noms C ++ normaux. Référence.

AVERTISSEMENT: Je ne suis pas un programmeur C ++, mais je connais très bien C. J’ai adapté ces appels à partir d’un code C que j’ai.

Aussi les démarques mettent ces étranges – mes soulignés.

Vous devriez juste pouvoir é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, il existe des méthodes pour ouvrir, fermer et envoyer des paquets sur 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 réponse est d’utiliser le drapeau c89 qui suit:

  -D_OE_SOCKETS 

Exemple suivant

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

Pour plus d’informations, consultez Options C89 dans le Guide de l’utilisateur z / OS XLC / C ++.