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.

Jax
la source

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);
Anthony Giorgio
la source
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

Chris Jester-Young
la source
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.

Robert Groves
la source
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

Fabio Ceconello
la source
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

pétillant
la source
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.

Federico
la source
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.

Chris Jester-Young
la source
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;
}
David Bryson
la source
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 ++.

Hope T.Aide
la source