Cómo usar la API de socket C en C ++ en z / OS

votos
126

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 diciéndome que AF_INETno está definido. ¿Me estoy perdiendo algo obvio, o podría estar relacionado con el hecho de que estoy haciendo esta codificación z/OSy mis problemas son mucho más complicados?


Actualización : Tras una investigación más profunda, descubrí que hay un #ifdefataque al que estoy golpeando. Aparentemente z/OSno es feliz a menos que defina con qué tipo de enchufes estoy usando:

#define _OE_SOCKETS

Ahora, personalmente no tengo idea de para qué _OE_SOCKETSsirve esto , así que si hay z/OSprogramadores de tomas por ahí (todos ustedes 3), ¿quizás podrían 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;
}

Salida de compilación / enlace:

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

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

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

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

Sin embargo, he notado que contiene uno de los siguientes:

#ifdef __cplusplus
  extern C {
#endif

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

Publicado el 01/08/2008 a las 13:13
fuente por usuario
En otros idiomas...                            


9 respuestas

votos
71

Tenga a mano una copia de los manuales de IBM:

Las publicaciones de IBM generalmente son muy buenas, pero necesita acostumbrarse a su formato, así como saber dónde buscar una respuesta. Encontrará con bastante frecuencia que una característica que desea usar está protegida por una "macro de prueba de características"

Debería pedirle a su amigable programador de sistemas que instale la Referencia de la biblioteca en tiempo de ejecución XL C / C ++: Páginas de manual en su sistema. Luego puede hacer cosas como "man connect" para abrir la página man para la API de socket connect (). Cuando hago eso, esto es lo que veo:

FORMATO

X / Abrir

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

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

Tomas de Berkeley

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

int connect(int socket, struct sockaddr *address, int address_len);
Respondida el 18/09/2009 a las 12:17
fuente por usuario

votos
34

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

#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 la situación aquí, sin embargo, debido a que nunca antes había usado z / OS, y mucho menos programado en él, no puedo decirlo definitivamente. :-PAG

Respondida el 01/08/2008 a las 13:22
fuente por usuario

votos
29

Consulte la sección de sockets de Servicios del sistema de z / OS UNIX en la Guía de programación de z / OS XL C / C ++. 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 debe poder acceder a él con la suficiente facilidad al encontrar la ubicación actual de la sección Soporte y descargas en ibm.com y buscar la documentación por título.

Respondida el 15/05/2009 a las 06:27
fuente por usuario

votos
23

El _OE_SOCKETS parece ser simplemente para habilitar / deshabilitar la definición de símbolos relacionados con el socket. No es raro en algunas bibliotecas tener un montón de macros para hacer eso, para asegurar que no está compilando / vinculando partes que no son necesarias. La macro no es estándar en otras implementaciones de sockets, parece ser algo específico para z / OS.

Eche un vistazo a esta página:
compilando y enlazando el programa z / VM C Sockets

Respondida el 11/10/2008 a las 01:38
fuente por usuario

votos
23

Entonces intenta

#define _OE_SOCKETS

antes de incluir sys / socket.h

Respondida el 21/09/2008 a las 13:37
fuente por usuario

votos
17

Es posible que desee echar un vistazo a cpp-sockets , un contenedor de C ++ para las llamadas al sistema de sockets. Funciona con muchos sistemas operativos (Win32, POSIX, Linux, * BSD). No creo que funcione con z / OS pero puede echar un vistazo a los archivos de inclusión que utiliza y tendrá muchos ejemplos de códigos probados que funcionan bien en otros sistemas operativos.

Respondida el 07/09/2008 a las 09:21
fuente por usuario

votos
15

@Jax: Lo extern "C"que importa, mucho. Si un archivo de encabezado no tiene uno, entonces (a menos que sea un archivo de encabezado solo en C ++), deberá adjuntarlo #includecon él:

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

Básicamente, cada vez que un programa de C ++ quiere vincularse a instalaciones basadas en C, 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 ++. Referencia.

Respondida el 01/08/2008 a las 14:40
fuente por usuario

votos
11

La respuesta es usar la bandera c89 que sigue:

 -D_OE_SOCKETS

Ejemplo 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 z / OS XLC / C ++ del usuario.

Respondida el 11/04/2011 a las 19:59
fuente por usuario

votos
11

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

También markdown puso estos extraños _ como mis caracteres de subrayado.

Debería poder escribir una clase de abstracción alrededor de los sockets 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, tenga métodos para abrir, cerrar y enviar paquetes por el socket.

Por ejemplo, la llamada abierta podría verse más o menos así:

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;
}
Respondida el 29/08/2008 a las 19:56
fuente por usuario

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more