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


158

Je vais avoir des problèmes à obtenir l'API C fonctionne correctement dans C++le z/OS.

Bien que j'inclus sys/socket.h, j'obtiens toujours des erreurs de compilation me disant que ce AF_INETn'est pas défini .

Est-ce que je rate quelque chose d'évident ou est-ce lié au fait qu'être en marche z/OSrend mes problèmes beaucoup plus compliqués?


Mise à jour : après une enquête plus approfondie, j'ai découvert qu'il y a un #ifdefque je frappe. Apparemment, z/OSje ne suis pas heureux à moins que je définisse avec quel «type» de sockets j'utilise:

#define _OE_SOCKETS

Maintenant, je n'ai personnellement aucune idée de ce à quoi cela _OE_SOCKETSsert réellement, donc s'il y a des z/OSprogrammeurs de sockets (vous trois), vous pourriez peut-être 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 #ifdefdéclaration.

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.

Réponses:


86

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 le XL C / C ++ Run-Time Library Reference: 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 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);

38

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 opinion à 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


32

Consultez la section Utilisation des sockets des services système z / OS UNIX dans 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 de la section Support & Downloads sur ibm.com et en recherchant la documentation par titre.


26

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 az / VM C


2
z / OS a autant de points communs avec z / VM que Windows avec Linux, donc je ne sais pas pourquoi vous avez publié ce lien.
paxdiablo

Notez que la macro _OE_SOCKETS apparaît dans les deux et semble avoir le même objectif. Ce qui n'est pas surprenant, car IBM a probablement utilisé 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 z / VM s'applique à z / OS, c'est juste le cas le plus similaire que j'ai trouvé.
Fabio Ceconello le

1
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 appropriés utilisés pour effectuer des appels de socket.
Anthony Giorgio

25

Alors essayez

#define _OE_SOCKETS

avant d'inclure sys / socket.h


19

Vous voudrez peut-être jeter un œil à 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.


18

@Jax: Le extern "C"truc est très important. 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 le joindre #include:

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, il extern "C"est vital. 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.


14

AVERTISSEMENT: Je ne suis pas un programmeur C ++, mais je connais très bien le C. J'ai adapté ces appels à partir d'un code 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;
}

Cela n'a rien à voir avec la question initiale.
Anthony Giorgio

13

Utilisez l'indicateur c89 suivant:

 -D_OE_SOCKETS

Exemple:

 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 ++.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.