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


158

我有越来越的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

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

Answers:


86

随手保存一份IBM手册副本:

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

您应该请友好的系统程序员在系统上安装XL C / C ++运行时库参考:手册页 。然后,您可以执行“ man connect”之类的操作来拉出套接字connect()API的手册页。当我这样做时,这就是我看到的:

格式

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

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

#include <sys/socket.h>

int
main()
{
    return AF_INET;
}

因此,我的看法是z / OS可能是这里的复杂因素,但是,因为我以前从未使用过z / OS,因此我从未明确使用过z / OS,因此我不能一概而论。:-P


32

请参阅《z / OS XL C / C ++编程指南》中的“ 使用z / OS UNIX系统服务”套接字部分。确保包含必要的头文件并使用适当的#define。

多年来,指向该文档的链接已经发生了变化,但是您应该可以通过在ibm.com上找到“ 支持与下载”部分的当前位置并按标题搜索文档来轻松地找到它。


26

_OE_SOCKETS似乎只是为了启用/禁用套接字相关符号的定义。在某些库中,有很多宏可以做到这一点,以确保您无需编译/链接不需要的部分,这种情况并不少见。该宏在其他套接字实现中不是标准的,它似乎是z / OS特有的。

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


2
z / OS与z / VM的共同点与Windows与Linux的共同点相同,所以我有点困惑为什么您发布了该链接。
paxdiablo

请注意,_OE_SOCKETS宏同时出现在两者中,并且似乎具有相同的用途。这不足为奇,因为IBM可能在两种产品中使用相同的代码库来支持套接字。我无意说z / VM文档适用于z / OS,这只是我发现的最相似的情况。
法比奥·塞科内洛

1
我认为这只是一个巧合。z / VM不使用z / OS语言环境产品,该产品提供用于进行套接字调用的相关头文件。
Anthony Giorgio

25

所以尝试

#define _OE_SOCKETS

在包含sys / socket.h之前


19

您可能想看看cpp-sockets,这是套接字系统调用的C ++包装器。它可用于许多操作系统(Win32,POSIX,Linux,* BSD)。我认为它不适用于z / OS,但您可以看一下它使用的包含文件,并且将有许多经过测试的代码示例,这些示例在其他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。我从我拥有的一些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;
}

这与原始问题无关。
Anthony Giorgio

13

答案是使用下面的c89标志:

 -D_OE_SOCKETS

示例如下;

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

有关更多信息,请在《 z / OS XLC / C ++用户指南》中查找“ C89选项”。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.