Pregunta

Tengo problemas para que la API de sockets C funcione correctamente en C++ en z/OS.

Aunque estoy incluyendo sys/socket.h, todavía recibo errores en tiempo de compilación que me dicen que AF_INET no está definido.

¿Me estoy perdiendo algo obvio o está relacionado con el hecho de que estar en z/OS ¿Hace mis problemas mucho más complicados?


Actualizar:Tras una mayor investigación, descubrí que hay una #ifdef que estoy pegando.Aparentemente z/OS no está contento a menos que defina con qué "tipo" de sockets estoy usando:

#define _OE_SOCKETS

Ahora bien, personalmente no tengo idea de qué es esto. _OE_SOCKETS es en realidad para, así que si hay alguno z/OS Hay programadores de sockets (ustedes 3), ¿tal vez podrían darme un resumen de cómo funciona todo esto?


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", 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.

Una verificación de sys/sockets.h incluye la definición que necesito y, hasta donde puedo decir, ninguna declaración #ifdef la bloquea.

Sin embargo, he notado que contiene lo siguiente:

#ifdef __cplusplus
  extern "C" {
#endif

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

¿Fue útil?

Solución

Tenga a mano una copia de los manuales de IBM:

Las publicaciones de IBM en general son muy buenas, pero es necesario acostumbrarse a su formato, además de saber dónde buscar una respuesta.Con bastante frecuencia encontrará que una función que desea utilizar está protegida por una "macro de prueba de funciones".

Debe pedirle a su amigable programador de sistemas que instale el Referencia de la biblioteca en tiempo de ejecución XL C/C++:Páginas man en su sistema.Luego, puede hacer cosas como "man connect" para abrir la página de manual de la API 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);

Enchufes Berkeley

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

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

Otros consejos

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, sin embargo, como nunca he usado z/OS antes, y mucho menos he programado en él, no puedo decir esto definitivamente.:-PAG

Ver el Utilización de sockets de servicios del sistema z/OS UNIX de la Guía de programación de z/OS XL C/C++.Asegúrese de incluir los archivos de encabezado necesarios y de utilizar los #defines adecuados.

El enlace al documento ha cambiado a lo largo de los años, pero debería poder acceder a él con bastante facilidad si encuentra la ubicación actual del Sección de soporte y descargas en ibm.com y buscar la documentación por título.

Así que intenta

#define _OE_SOCKETS

antes de incluir sys/socket.h

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

Échale un vistazo a esta página:
Compilación y vinculación de un programa de sockets z/VM C

Quizás quieras echar un vistazo a enchufes-cpp, 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 puedes echar un vistazo a los archivos de inclusión que utiliza y tendrás muchos ejemplos de código probado que funciona bien en otros sistemas operativos.

@Jax:El extern "C" La cosa importa, muchísimo.Si un archivo de encabezado no tiene uno, entonces (a menos que sea un archivo de encabezado solo de C++), deberá adjuntar su #include con eso:

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

Básicamente, en cualquier momento en el que un programa C++ quiera vincularse 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 serán alterados, como lo harían los nombres normales de C++. Referencia.

DESCARGO DE RESPONSABILIDAD:No soy programador de C++, pero conozco muy bien C.Adapté estas llamadas de algún código C que tengo.

También Markdown puso estos _ extraños como guiones bajos.

Deberías 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 convocatoria abierta podría verse 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;
}

La respuesta es utilizar el indicador c89 que sigue:

 -D_OE_SOCKETS

A continuación se muestra el ejemplo;

 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 de z/OS XLC/C++.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top