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

J'ai rencontré des problèmes pour que l'API C sockets fonctionne correctement en C ++. Plus précisément, bien que j'inclue sys / socket.h , j'obtiens toujours des erreurs de compilation en me disant que AF_INET n'est pas défini. Ai-je manqué quelque chose d'évident, ou cela pourrait-il être lié au fait que je fais ce codage sur z / OS et que mes problèmes sont beaucoup plus compliqués?


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

Maintenant, personnellement, je n'ai aucune idée de ce qu'est réellement ce _OE_SOCKETS , donc si des programmeurs de sockets z / OS sont là (tous les 3), peut-être pourriez-vous donner moi un aperçu de la façon dont tout cela fonctionne?


Bien sûr, je peux poster une application de test.

#include 

int main()
{
    return AF_INET;
}

Compiler / Lier la sortie:

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

"./inet.C", ligne 5.16: CCN5274 (S) La recherche de nom pour "AF_INET" n'a pas trouvé de déclaration.

CCN0797 (I) La compilation a échoué pour le fichier ./inet.C. Fichier objet non créé.

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 un des éléments suivants:

#ifdef __cplusplus
  extern "C" {
#endif

qui encapsule essentiellement le fichier entier. Je ne sais pas si c'est important.

0
ajouté édité
Vues: 20

9 Réponses

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

#include 

int
main()
{
    return AF_INET;
}

Donc, mon avis 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é, je ne peux pas le dire définitivement. :-P

0
ajouté

@Jax: La chose extern "C" est très importante. 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 C ++ uniquement), vous devez inclure votre #include avec celui-ci:

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
ajouté

Voir la section Utilisation des sockets des services système z / OS UNIX dans le Guide de programmation z / OS XL C / C ++. Assurez-vous d'inclure les fichiers d'en-tête nécessaires et d'utiliser les #defines appropriés.

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
ajouté

Alors essayez

#define _OE_SOCKETS

avant d'inclure sys / socket.h

0
ajouté

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, pour s'assurer que vous ne compilez pas / ne reliez pas des parties non nécessaires. La macro n'est pas standard dans les autres implémentations de sockets, elle semble être spécifique à z / OS.

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

0
ajouté
z / OS a autant de points communs avec z / VM que Windows avec Linux, donc je suis un peu surpris de savoir pourquoi vous avez posté ce lien.
ajouté l'auteur paxdiablo, source
Notez que la macro _OE_SOCKETS apparaît dans les deux et semble avoir le même but. Ce qui n'est pas surprenant, car IBM utilisait probablement la même base de code pour la prise en charge des sockets dans les deux produits. Je n'avais pas l'intention de dire que la documentation de z / VM s'applique à z / OS, c'est juste le cas le plus similaire que j'ai trouvé.
ajouté l'auteur Fabio Ceconello, source
Je pense que c'est juste une coïncidence. z / VM n'utilise pas le produit z / OS Language Environment, qui fournit les fichiers d'en-tête pertinents utilisés pour effectuer des appels de socket.
ajouté l'auteur Anthony Giorgio, source

DISCLAIMER: Je ne suis pas un programmeur C ++, mais je sais très bien C. je adapté ces appels à partir de quelque code C que j'ai.

Also markdown put these strange _ as my underscores.

Vous devriez juste ê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, ayez 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;
}
0
ajouté
Cela n'a rien à voir avec la question originale.
ajouté l'auteur Anthony Giorgio, source

Vous pouvez jeter un oeil à cpp-sockets , un wrapper C ++ pour les appels système 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 regarder les fichiers d'inclusion qu'il utilise et vous aurez de nombreux exemples de code testés qui fonctionnent bien sur d'autres systèmes d'exploitation.

0
ajouté

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

Les publications d'IBM sont généralement très bonnes, mais vous devez vous habituer à leur FORMAT, ainsi que savoir où chercher une réponse. Vous trouverez 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 amical d'installer le XL C / Référence de la bibliothèque d'exécution C ++: Man Pages sur votre système. Ensuite, vous pouvez faire des choses comme "man connect" pour afficher la page man de l'API socket connect (). Quand je fais ça, c'est ce que je vois:

FORMAT

X / Ouvert

#define _XOPEN_SOURCE_EXTENDED 1
#include 

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

Berkeley Douilles

#define _OE_SOCKETS
#include 
#include 

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

La réponse est utiliser le drapeau 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 de z / OS XLC / C ++.

0
ajouté