Як використовувати API socket C в C ++ на z / OS


158

У мене виникають питання , отримати З Sockets API для роботи належним чином 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

який інкапсулює в основному весь файл? Не впевнений, чи це має значення.

Відповіді:


86

Зберігайте під рукою копію посібників IBM:

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

Ви можете попросити свого доброзичливого системного програміста встановити XL C / C ++ Бібліотеку часу виконання: Сторінки Man у вашій системі. Тоді ви можете виконати такі дії, як "man connect", щоб відкрити довідкову сторінку для API socket 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);

38

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

#include <sys/socket.h>

int
main()
{
    return AF_INET;
}

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


32

Дивіться розділ Використання гнізд системних служб z / OS UNIX у посібнику з програмування z / OS XL C / C ++. Переконайтеся, що ви включаєте необхідні файли заголовків та використовуєте відповідні #defines.

Посилання на документ змінюється протягом багатьох років, але вам слід отримати доступ до нього досить легко, знайшовши поточне місце розташування розділу " Підтримка та завантаження" на ibm.com та шукаючи документацію за назвою.


26

Здається, _OE_SOCKETS - це просто включити / відключити визначення символів, пов'язаних з сокетом. У деяких бібліотеках не рідкість мати макрос для цього, щоб переконатися, що ви не збираєте / не зв'язуєте деталі. Макрос не є стандартним для інших реалізацій сокетів, він здається чимось специфічним для z / OS.

Погляньте на цю сторінку:
Компіляція та зв’язування програми розеток az / VM C


2
z / OS має стільки спільного з z / VM, як і Windows з Linux, тому я трохи здивований, чому ви розмістили це посилання.
paxdiablo

Зауважте, що макрос _OE_SOCKETS відображається в обох і, схоже, має однакове призначення. Що не дивно, оскільки, ймовірно, IBM використовував однакову базу коду для підтримки сокетів в обох продуктах. Я не мав наміру говорити, що z / VM документація стосується z / OS, це просто найбільш подібний випадок, який я знайшов.
Фабіо Чеконелло

1
Я думаю, що це просто збіг. z / VM не використовує продукт z / OS Language Environment, який надає відповідні файли заголовків, які використовуються для здійснення дзвінків у сокет.
Ентоні Джорджіо


19

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


18

@Jax: Справа extern "C"важлива, дуже-дуже. Якщо у файлі заголовка його немає, то (якщо це не лише файл C ++ - лише заголовок), вам доведеться долучити #includeдо нього:

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

В основному, в будь-який час, коли програма C ++ хоче зв’язатися з об'єктами на базі C, extern "C"це життєво важливо. На практиці це означає, що імена, які використовуються у зовнішніх посиланнях, не підлягатимуть зловмисникам, як звичайні імена C ++. Довідково.


14

ВІДПОВІДАЛЬНІСТЬ: Я не програміст на 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;
}

Це не має нічого спільного з початковим питанням.
Ентоні Джорджіо

13

Відповідь - використовувати прапор c89, який наступним чином:

 -D_OE_SOCKETS

Приклад випливає;

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

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.