Domanda

Ho problemi a far funzionare correttamente l'API dei socket C in C++ z/OS.

Anche se sto includendo sys/socket.h, ricevo ancora errori in fase di compilazione che me lo dicono AF_INET non è definito.

Mi sto perdendo qualcosa di ovvio, o questo è legato al fatto che essere attivo z/OS rende i miei problemi molto più complicati?


Aggiornamento:Dopo ulteriori indagini, ho scoperto che esiste un file #ifdef che sto colpendo.Apparentemente z/OS non è felice a meno che non definisca quale "tipo" di socket sto utilizzando con:

#define _OE_SOCKETS

Ora, personalmente non ho idea di cosa questo _OE_SOCKETS è in realtà per, quindi se presente z/OS ci sono programmatori di socket (tutti e 3), forse potreste darmi un riassunto di come funziona tutto questo?


Prova l'app

#include <sys/socket.h>

int main()
{
    return AF_INET;
}

Compila/collega 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.

Un controllo di sys/sockets.h include la definizione di cui ho bisogno e, per quanto ne so, non è bloccato da alcuna istruzione #ifdef.

Ho notato però che contiene quanto segue:

#ifdef __cplusplus
  extern "C" {
#endif

che incapsula sostanzialmente l'intero file.Non sono sicuro che sia importante.

È stato utile?

Soluzione

Tieni a portata di mano una copia dei manuali IBM:

Le pubblicazioni IBM sono generalmente molto buone, ma è necessario abituarsi al loro formato, oltre a sapere dove cercare una risposta.Scoprirai molto spesso che una funzionalità che desideri utilizzare è protetta da una "macro di test delle funzionalità"

Dovresti chiedere al tuo amichevole programmatore di sistema di installare il file Riferimento alla libreria runtime XL C/C++:Pagine uomo sul tuo sistema.Quindi puoi fare cose come "man connect" per aprire la pagina man per l'API socket connect().Quando lo faccio, questo è quello che vedo:

FORMATO

X/Apri

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

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

Prese Berkeley

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

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

Altri suggerimenti

Non ho avuto problemi con l'utilizzo dell'API dei socket BSD in C++, in GNU/Linux.Ecco il programma di esempio che ho usato:

#include <sys/socket.h>

int
main()
{
    return AF_INET;
}

Quindi la mia opinione a riguardo è che z/OS è probabilmente il fattore complicante qui, tuttavia, poiché non ho mai usato z/OS prima, tanto meno programmato al suo interno, non posso dirlo in modo definitivo.:-P

Vedi il Utilizzo dei socket dei servizi di sistema z/OS UNIX sezione nella Guida alla programmazione z/OS XL C/C++.Assicurati di includere i file di intestazione necessari e di utilizzare le #defines appropriate.

Il collegamento al documento è cambiato nel corso degli anni, ma dovresti riuscire ad accedervi abbastanza facilmente trovando la posizione attuale del documento Sezione Supporto e download SU ibm.com e cercare la documentazione per titolo.

Allora prova

#define _OE_SOCKETS

prima di includere sys/socket.h

Sembra che _OE_SOCKETS serva semplicemente ad abilitare/disabilitare la definizione dei simboli relativi al socket.Non è raro in alcune librerie avere un sacco di macro per farlo, per assicurarsi che non si stiano compilando/collegando parti non necessarie.La macro non è standard in altre implementazioni socket, sembra essere qualcosa di specifico per z/OS.

Dai un'occhiata a questa pagina:
Compilazione e collegamento di un programma z/VM C Sockets

Potresti voler dare un'occhiata a socket cpp, un wrapper C++ per le chiamate di sistema socket.Funziona con molti sistemi operativi (Win32, POSIX, Linux, *BSD).Non penso che funzionerà con z/OS ma puoi dare un'occhiata ai file di inclusione che utilizza e avrai molti esempi di codice testato che funziona bene su altri sistemi operativi.

@Jax:IL extern "C" la cosa conta, moltissimo.Se un file di intestazione non ne ha uno, allora (a meno che non sia un file di intestazione solo C++), dovresti racchiudere il tuo #include con esso:

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

Fondamentalmente, ogni volta che un programma C++ vuole collegarsi a strutture basate su C, il file extern "C" è vitale.In termini pratici, significa che i nomi utilizzati nei riferimenti esterni non verranno alterati, come farebbero i normali nomi C++. Riferimento.

DISCLAIMER:Non sono un programmatore C++, tuttavia conosco molto bene il C.Ho adattato queste chiamate da un codice C che ho.

Anche il ribasso ha messo questi strani _ come sottolinea il mio.

Dovresti semplicemente essere in grado di scrivere una classe di astrazione attorno ai socket C con qualcosa del genere:

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

Quindi disponi di metodi per aprire, chiudere e inviare pacchetti lungo il socket.

Ad esempio, la chiamata aperta potrebbe assomigliare a questa:

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 risposta è utilizzare il flag c89 che segue:

 -D_OE_SOCKETS

Segue l'esempio;

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

Per ulteriori informazioni cercare Opzioni C89 nella Guida per l'utente di z/OS XLC/C++.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top