Сведения о вопросе

Htmlщик

16:03, 1st July, 2020

Теги

c++   c   sockets   mainframe   zos    

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

Просмотров: 517   Ответов: 9

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

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

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


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

#define _OE_SOCKETS

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


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

#include <sys/socket.h>

int main()
{
    return AF_INET;
}

Компиляции/Link Выход :

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

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



  Сведения об ответе

#hash

18:03, 1st July, 2020

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

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

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

FORMAT

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


  Сведения об ответе

ASSembler

18:03, 1st July, 2020

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

#include <sys/socket.h>

int
main()
{
    return AF_INET;
}

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


  Сведения об ответе

DO__IT

18:03, 1st July, 2020

Ознакомиться с использованием z/OS системы UNIX услуг розетки секции в z/OS в ХL C/C++ руководство по программированию. Убедитесь, что вы включаете необходимые заголовочные файлы и используете соответствующий #defines.

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


  Сведения об ответе

pumpa

18:03, 1st July, 2020

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

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


  Сведения об ответе

PAGE

18:03, 1st July, 2020

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

#define _OE_SOCKETS

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


  Сведения об ответе

park

18:03, 1st July, 2020

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


  Сведения об ответе

DINO

18:03, 1st July, 2020

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

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

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


  Сведения об ответе

nYU

18:03, 1st July, 2020

Ответ заключается в использовании следующего флага c89:

 -D_OE_SOCKETS

Пример следующий;

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

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


  Сведения об ответе

PIRLO

18:03, 1st July, 2020

Отказ от ответственности: я не программист C++, однако я очень хорошо знаю C. Я адаптировал эти вызовы из какого-то кода C, который у меня есть.

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

Вы просто должны быть в состоянии написать класс абстракции вокруг сокетов 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;
}


Ответить на вопрос

Чтобы ответить на вопрос вам нужно войти в систему или зарегистрироваться