Как использовать API-интерфейс сокета C в С++ для z/OS - программирование

Как использовать API-интерфейс сокета C в С++ для z/OS

У меня возникли проблемы с тем, что API C сокетов корректно работает на С++. В частности, хотя я включаю 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", строка 5.16: CCN5274 (S) Поиск имени для "AF_INET" не нашел объявления.

CCN0797 (I) Ошибка компиляции файла. /inet.C. Файл объекта не создан.

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

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

#ifdef __cplusplus
  extern "C" {
#endif

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

4b9b3361

Ответ 1

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

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

Вы должны попросить вашего дружелюбного системного программиста установить XL C/С++ Справочник по времени выполнения: Man Pages в вашей системе. Затем вы можете сделать что-то вроде "man connect", чтобы поднять справочную страницу для 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);

Berkeley Sockets

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

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

Ответ 2

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

#include <sys/socket.h>

int
main()
{
    return AF_INET;
}

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

Ответ 3

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

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

Ответ 4

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

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

Ответ 5

Итак, попробуйте

#define _OE_SOCKETS

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

Ответ 6

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

Ответ 7

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

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

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

Ответ 8

ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ: Я не программист на С++, однако я очень хорошо знаю 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;
}

Ответ 9

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

 -D_OE_SOCKETS

Пример:

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

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