Как использовать 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
который инкапсулирует в основном весь файл. Не уверен, имеет ли это значение.
Ответы
Ответ 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/С++.