Как использовать API сокетов C в C ++ в z / OS - PullRequest
137 голосов
/ 01 августа 2008

У меня проблемы с настройкой 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 ]

78 голосов
/ 18 сентября 2009

Храните копию руководств IBM под рукой:

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

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

FORMAT

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);
36 голосов
/ 01 августа 2008

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

#include <sys/socket.h>

int
main()
{
    return AF_INET;
}

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

31 голосов
/ 15 мая 2009

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

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

25 голосов
/ 11 октября 2008

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

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

25 голосов
/ 21 сентября 2008

Так что попробуйте

#define _OE_SOCKETS

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

19 голосов
/ 07 сентября 2008

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

17 голосов
/ 01 августа 2008

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

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

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

13 голосов
/ 11 апреля 2011

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

 -D_OE_SOCKETS

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

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

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

13 голосов
/ 29 августа 2008

ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ: Я не программист на 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;
}
...