Question

J'ai des problèmes pour faire fonctionner correctement l'API des sockets C en C++ sur z/OS.

Même si j'inclus sys/socket.h, j'obtiens toujours des erreurs de compilation me disant que AF_INET n'est pas défini.

Est-ce que j'ai raté quelque chose d'évident, ou est-ce lié au fait que le fait d'être sur z/OS rend mes problèmes beaucoup plus compliqués ?


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 satisfait à moins que je définisse le "type" de sockets que j'utilise avec :

#define _OE_SOCKETS

Maintenant, personnellement, je n'ai aucune idée de ce que c'est _OE_SOCKETS est en fait pour, donc le cas échéant z/OS il existe des programmeurs de sockets (vous tous les trois), 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;
}

Sortie Compiler/Lier :

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 pratiquement tout le fichier.Je ne sais pas si c'est important.

Était-ce utile?

La solution

Conservez 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és".

Vous devriez demander à votre programmeur système convivial d'installer le Référence de la bibliothèque d'exécution XL C/C++ :Pages de manuel 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, voici ce que je vois :

FORMAT

X/Ouvert

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

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

Prises Berkeley

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

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

Autres conseils

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 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é dedans, je ne peux pas le dire avec certitude.:-P

Voir le 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.

Le lien vers le document a changé au fil des années, mais vous devriez pouvoir y accéder assez facilement en trouvant l'emplacement actuel du Section Assistance et téléchargements sur ibm.com et rechercher la documentation par titre.

Alors essaie

#define _OE_SOCKETS

avant d'inclure sys/socket.h

Le _OE_SOCKETS semble être simplement destiné à 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 garantir que vous ne compilez/liez pas 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 oeil à cette page:
Compilation et liaison d'un programme z/VM C Sockets

Vous voudrez peut-être jeter un oeil à prises cpp, 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.

@Jax :Le extern "C" la chose compte, vraiment, beaucoup.Si un fichier d'en-tête n'en a pas, alors (sauf s'il s'agit d'un fichier d'en-tête uniquement en C++), vous devrez joindre votre #include avec ça:

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

Fondamentalement, chaque fois qu'un programme C++ souhaite se connecter à des fonctionnalités basées sur C, le extern "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.

CLAUSE DE NON-RESPONSABILITÉ: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 traits de soulignement.

Vous devriez simplement 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;
};

Ayez ensuite des méthodes pour ouvrir, fermer et envoyer des paquets sur le socket.

Par exemple, l’appel ouvert pourrait 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 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++.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top