Вопрос

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

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

Это было полезно?

Решение

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

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

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

ФОРМАТ

X/Открыть

#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 раздел в Руководстве по программированию на z/OS XL C/C++.Убедитесь, что вы включили необходимые файлы заголовков и используете соответствующие #defines.

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

Поэтому постарайтесь

#define _OE_SOCKETS

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

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

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

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

@Джакс:А 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++.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top