Как использовать API сокетов C в C++ в z/OS

У меня проблемы с настройкой API сокетов C для правильной работы в C++ на z/OS,

Хотя я в том числе sys/socket.hЯ все еще получаю ошибки времени компиляции, говорящие мне, что AF_INET не определено.

Я упускаю что-то очевидное, или это связано с тем, что на z/OS делает мои проблемы намного сложнее?


Обновление: После дальнейшего расследования я обнаружил, что есть #ifdef что я бью. По-видимому z/OS не рад, если я не определю, какой "тип" сокетов я использую с:

#define _OE_SOCKETS

Теперь я лично понятия не имею, что это _OE_SOCKETS на самом деле для, так что если есть z/OS программисты сокетов (все трое из вас), возможно, вы могли бы дать мне краткое изложение того, как все это работает?


Тестовое приложение

#include <sys/socket.h>

int main()
{
    return AF_INET;
}

Выход компиляции / ссылки:

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.

Проверка sys / sockets.h включает в себя определение, которое мне нужно, и, насколько я могу судить, оно не блокируется никакими операторами #ifdef.

Однако я заметил, что он содержит следующее:

#ifdef __cplusplus
  extern "C" {
#endif

который инкапсулирует в основном весь файл. Не уверен, если это имеет значение.

9 ответов

Решение

Держите копию руководств IBM под рукой:

Публикации IBM, как правило, очень хороши, но вам нужно привыкнуть к их формату, а также знать, где искать ответ. Довольно часто вы обнаружите, что функция, которую вы хотите использовать, защищена "макросом проверки возможностей".

Вам следует попросить вашего дружественного системного программиста установить справочную библиотеку XL C / C++: справочные страницы в вашей системе. Затем вы можете сделать что-то вроде "man connect", чтобы открыть страницу man для API сокета connect (). Когда я это делаю, вот что я вижу:

ФОРМАТ

X/Open

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

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

Беркли Розетки

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

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

У меня не было проблем с использованием API сокетов BSD в C++, в GNU/Linux. Вот пример программы, которую я использовал:

#include <sys/socket.h>

int
main()
{
    return AF_INET;
}

Поэтому я полагаю, что z/OS, вероятно, является здесь усложняющим фактором, поскольку я никогда раньше не использовал z/OS, тем более запрограммирован в нем, я не могу сказать этого окончательно.:-П

См. Раздел Использование сокетов z/OS UNIX System Services в Руководстве по программированию z/OS XL C/C++. Убедитесь, что вы включаете необходимые заголовочные файлы и используете соответствующие #defines.

Ссылка на документ с годами менялась, но вы сможете достаточно легко получить к ней доступ, найдя текущее местоположение раздела Support & Downloads на ibm.com и выполнив поиск по названию документации.

Так что постарайтесь

#define _OE_SOCKETS

прежде чем включить sys/socket.h

_OE_SOCKETS, по-видимому, просто включает / отключает определение символов, связанных с сокетом. В некоторых библиотеках не редкость иметь для этого кучу макросов, чтобы гарантировать, что вы не компилируете / связываете ненужные части. Макрос не является стандартным в других реализациях сокетов, он кажется чем-то специфичным для z/OS.

Посмотрите на эту страницу:
Компиляция и компоновка программы z/VM C Sockets

Возможно, вы захотите взглянуть на cpp-sockets, оболочку C++ для системных вызовов сокетов. Работает со многими операционными системами (Win32, POSIX, Linux, *BSD). Я не думаю, что это будет работать с z/OS, но вы можете взглянуть на включаемые файлы, которые он использует, и у вас будет много примеров проверенного кода, который хорошо работает на других ОС.

@Jax: The extern "C" вещь очень важна. Если заголовочный файл не имеет его, тогда (если это не заголовочный файл только для C++), вам придется заключить #include с этим:

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

По сути, в любое время, когда программа на C++ хочет подключиться к средствам на основе C, extern "C" жизненно важно. На практике это означает, что имена, используемые во внешних ссылках, не будут искажены, как обычные имена C++. Ссылка.

ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ: Я не программист C++, однако я очень хорошо знаю C. Я адаптировал эти вызовы из некоторого кода на C, который у меня есть.

Также уценка поставить эти странные _ как мои подчеркивания.

Вы должны просто иметь возможность написать абстракционный класс вокруг сокетов C примерно так:

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

Затем есть методы для открытия, закрытия и отправки пакетов по сокету.

Например, открытый вызов может выглядеть примерно так:

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

Ответ - используйте флаг c89, который следует:

 -D_OE_SOCKETS

Пример следует;

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

Для получения дополнительной информации см. Параметры C89 в Руководстве пользователя z/OS XLC/C++.

Другие вопросы по тегам