2008-08-01 19 views
124

He estado teniendo problemas para que la API de sockets C funcione correctamente en C++. Específicamente, aunque estoy incluyendo sys/socket.h, sigo recibiendo errores de tiempo de compilación que me dicen que AF_INET no está definido. ¿Me estoy perdiendo algo obvio, o podría estar relacionado con el hecho de que estoy haciendo esta codificación en z/OS y mis problemas son mucho más complicados?Cómo usar la API de socket C en C++ en z/OS


actualización: Tras realizar investigaciones adicionales, he descubierto que hay una #ifdef que estoy golpeando. Al parecer z/OS no es feliz a menos que definen qué "tipo" de tomas que estoy usando con:

#define _OE_SOCKETS 

Ahora, tengo personalmente ninguna idea de lo que es en realidad para _OE_SOCKETS, por lo que si alguna z/OS zócalos programadores están fuera allí (todos ustedes 3), ¿quizás podría darme un resumen de cómo funciona todo esto?


Claro que puedo publicar una aplicación de prueba.

#include <sys/socket.h> 

int main() 
{ 
    return AF_INET; 
} 

Compilar/Salida de enlace:

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

"./inet.C", la línea de 5,16: CCN5274 (S) La búsqueda de nombre para "AF_INET" no encontró una declaración.

CCN0797 (I) Error de compilación para el archivo ./inet.C. Archivo de objeto no creado.

Una comprobación de sys/sockets.h incluye la definición que necesito, y hasta donde puedo decir, no está siendo bloqueada por ninguna instrucción #ifdef.

Sin embargo, he notado que contiene una la siguiente:

#ifdef __cplusplus 
    extern "C" { 
#endif 

que encapsula básicamente todo el archivo. No estoy seguro de si importa

Respuesta

69

Mantener una copia de los manuales de IBM útil:

Las publicaciones de IBM son en general muy bueno, pero hay que acostumbrarse a su formato, así como saber dónde buscar una respuesta. Encontrará con bastante frecuencia que una característica que desea utilizar está protegida por una "macro de prueba de función"

Debe pedirle a su amigable programador de sistema que instale el XL C/C++ Run-Time Library Reference: Man Pages en su sistema. A continuación, puede hacer cosas como "hombre Conectar" para tirar de la página del manual para la toma de conectar() de la API.Cuando lo hago, esto es lo que veo:

FORMATO

X/Open

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

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

Berkeley sockets

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

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

No he tenido problemas para usar la API de sockets BSD en C++, en GNU/Linux. Aquí está el programa de ejemplo he utilizado:

#include <sys/socket.h> 

int 
main() 
{ 
    return AF_INET; 
} 

Así que mi opinión sobre esto es que z/OS es probablemente el factor que complica, sin embargo, porque nunca he utilizado z/OS antes, mucho menos programado en el mismo, No puedo decir esto definitivamente. :-P

15

@Jax: La cosa extern "C" importa, muchísimo. Si un archivo de cabecera no tiene uno, entonces (a menos que sea un C++ - Sólo archivo de cabecera), que tendría que incluir su #include con él:

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

Básicamente, en cualquier momento en un programa en C++ quiere enlazar a Instalaciones basadas en C, el extern "C" es vital. En términos prácticos, significa que los nombres utilizados en las referencias externas no se destrozarán, como lo harían los nombres normales de C++. Reference.

11

DESCARGO DE RESPONSABILIDAD: No soy un programador de C++, sin embargo, sé C realmente bien. I adapté estas llamadas de algún código C que tengo.

rebaja también puso estos extraños _ como mis guiones.

Usted sólo debe ser capaz de escribir una clase de abstracción alrededor de los zócalos C con algo como esto:

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

Luego tienen métodos para abrir, cerrar, y el envío de paquetes por el zócalo.

Por ejemplo, la llamada abierta podría ser algo como esto:

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

Esto no tiene nada que ver con la pregunta original. –

17

Es posible que desee echar un vistazo a cpp-sockets, un C++ envoltura para las llamadas al sistema de sockets. Funciona con muchos sistemas operativos (Win32, POSIX, Linux, * BSD). Yo no creo que vaya a trabajar con z/OS, pero se puede echar un vistazo a los ficheros include se utiliza y que tendrá muchos ejemplos de código probado que funciona bien en otros sistemas operativos.

23

Así que trate

#define _OE_SOCKETS 

antes de incluir sys/socket.h

23

El _OE_SOCKETS parece ser simplemente para activar/desactivar la definición de los símbolos relacionados con socket. No es raro que en algunas bibliotecas que tienen un montón de macros para hacer eso, para asegurar que usted no está compilar/enlazar partes no necesarias. La macro no es estándar en otras implementaciones tomas de corriente, que parece ser algo específico para z/OS.

Tome un vistazo a esta página:
Compiling and Linking a z/VM C Sockets Program

+2

z/OS tiene tanto en común con z/VM como Windows con Linux, así que estoy un poco confundido por qué has publicado ese enlace. – paxdiablo

+0

Observe que la macro _OE_SOCKETS aparece en ambos y parece tener el mismo objetivo. Lo cual no es sorprendente, ya que probablemente IBM usó la misma base de código para el soporte de socket en ambos productos. No tenía intención de decir que la documentación de z/VM se aplica a z/OS, es el caso más similar que encontré. –

+1

Creo que es solo una coincidencia. z/VM no utiliza el producto z/OS Language Environment, que proporciona los archivos de cabecera relevantes utilizados para realizar llamadas de socket. –

29

Ver las Uso/enchufes servicios del sistema UNIX OS z sección en el z/OS XL C/C++ Guía de programación. Asegúrese de incluir los archivos de encabezado necesarios y el uso de #defines apropiados.

El enlace al documento ha cambiado a lo largo de los años, pero debería poder acceder a él con la localización actual del Support & Downloads section en y buscar la documentación por título.

11

La respuesta es usar la bandera c89 que sigue:

-D_OE_SOCKETS 

Exampl e sigue;

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

Para obtener más información, busque opciones de C89 en la Guía del usuario z/OS XLC/C++.