如何在z/OS上的C++中使用C套接字API

Jax 137 c c++ sockets mainframe zos

我在让C套接字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

它基本上封装了整个文件.不确定是否重要.

Anthony Gior.. 77

保留IBM手册的副本:

IBM出版物通常非常好,但您需要习惯他们的格式,以及知道在哪里寻找答案.你经常会发现你想要使用的功能受到"功能测试宏"的保护

您应该让您的友好系统程序员在您的系统上安装XL C/C++运行时库参考:手册页 .然后,您可以执行"man connect"之类的操作,以获取socket connect()API的手册页.当我这样做时,这就是我所看到的:

格式

在X/Open

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


Chris Jester.. 37

我在GNU/Linux中使用C++中的BSD套接字API没有遇到任何麻烦.这是我使用的示例程序:

#include <sys/socket.h>

int
main()
{
    return AF_INET;
}

所以我对此的看法是,z/OS可能是这里的复杂因素,但是,因为我以前从未使用过z/OS,更不用说编程了,我不能肯定地说.:-P


Robert Grove.. 31

请参见" z/OS XL C/C++编程指南"中的" 使用z/OS UNIX系统服务套接字"部分.确保包含必要的头文件并使用适当的#defines.

到文档的链接已经改变多年来,但你应该能够找到的当前位置得到它很轻松地支持和下载部分ibm.com和标题搜索文档.


fizzer.. 25

所以试试吧

#define _OE_SOCKETS

在包含sys/socket.h之前


Fabio Cecone.. 25

_OE_SOCKETS似乎只是启用/禁用与套接字相关的符号的定义.在某些库中,有一堆宏来执行此操作并不罕见,以确保您不编译/链接不需要的部分.宏在其他套接字实现中不是标准的,它似乎是z/OS特有的.

看一下这个页面:
编译和链接z/VM C套接字程序

  • z/OS与z/VM有很多共同点,就像Windows对Linux一样,所以我有点困惑为什么你发布了这个链接. (2认同)

用户甲.. 19

您可能需要查看cpp-sockets,它是套接字系统调用的C++包装器.它适用于许多操作系统(Win32,POSIX,Linux,*BSD).我认为它不适用于z/OS,但你可以看看它使用的包含文件,你会有很多经过测试的代码示例,这些代码在其他操作系统上运行良好.


Chris Jester.. 18

@Jax:extern "C"事情非常重要.如果头文件没有头文件,那么(除非它是一个只有C++的头文件),你必须#include用它包围你:

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

基本上,在C++程序想要链接到基于C的设施的任何时候,这extern "C"都是至关重要的.实际上,它意味着外部引用中使用的名称不会像正常的C++名称那样被破坏.参考.


用户甲.. 13

免责声明:我不是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;
};

然后有方法在套接字下打开,关闭和发送数据包.

例如,open调用可能如下所示:

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

有关更多信息,请参阅z/OS XLC/C++用户指南中的C89选项.