如何在z / OS上使用C ++中的C socket API

我一直有问题让C的套接字API在C ++中正常工作。 具体来说,虽然我包括sys/socket.h ,但仍然有编译时错误告诉我AF_INET没有被定义。 我是否错过了一些显而易见的东西,或者这可能与我在z/OS上进行这种编码的事实有关,而且我的问题更加复杂?


更新 :经过进一步的调查,我发现有一个#ifdef我打。 显然z/OS是不开心,除非我定义我使用的套接字“types”:

 #define _OE_SOCKETS 

现在,我个人不知道这个_OE_SOCKETS实际上是什么,所以如果有任何z/OS套接字程序员在那里(你们全部3个),也许你可以给我一个如何工作的概要?


当然,我可以发布testing应用程序。

 #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”的名称查找没有find声明。

(I)编译文件./inet.C失败。 目标文件未创build。

sys / sockets.h的检查确实包括了我所需要的定义,就我所知,它并没有被任何#ifdef语句阻塞。

但是我注意到它包含以下内容:

 #ifdef __cplusplus extern "C" { #endif 

它基本上封装了整个文件。 不知道是否重要。

方便地保留IBM手册的副本:

  • z / OS V1R11.0 XL C / C ++编程指南
  • z / OS V1R11.0 XL C / C ++运行时库参考

IBM的出版物一般都非常好,但是您需要习惯他们的格式,以及知道在哪里寻找答案。 你会经常发现你想要使用的function是由“functiontestingmacros”来保护的,

你应该让你友好的系统程序员在你的系统上安装XL C / C ++运行库参考:手册页 。 然后你可以做一些事情,比如“man connect”来为套接字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); 

伯克利sockets

 #define _OE_SOCKETS #include <sys/types.h> #include <sys/socket.h> int connect(int socket, struct sockaddr *address, int address_len); 

我在GNU / Linux中使用C ++中的BSD套接字API没有任何问题。 以下是我使用的示例程序:

 #include <sys/socket.h> int main() { return AF_INET; } 

所以我认为z / OS在这里可能是一个复杂的因素,然而,因为我以前从来没有使用过z / OS,更不用说编程了,所以我不能说这是明确的。 😛

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

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

_OE_SOCKETS似乎只是为了启用/禁用套接字相关符号的定义。 在一些图书馆里有一堆macros来做这件事情,这是不常见的,以确保你不编译/链接不需要的部分。 这个macros在其他套接字实现中不是标准的,它似乎是z / OS特有的。

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

所以试试

 #define _OE_SOCKETS 

在包含sys / socket.h之前

你可能想看看cpp-sockets ,一个用于套接字系统调用的C ++封装器。 它适用于许多操作系统(Win32,POSIX,Linux,* BSD)。 我不认为它可以在z / OS上工作,但是你可以看看它使用的包含文件,你会有很多testing代码的例子,在其他操作系统上运行良好。

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

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

基本上,只要C ++程序想要链接到基于C的设备, extern "C"就非常重要。 实际上,这意味着在外部引用中使用的名称不会像通常的C ++名字那样被破坏。 参考。

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

然后有方法来打开,closures和发送数据包的sockets。

例如,公开呼叫可能看起来像这样:

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

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

  -D_OE_SOCKETS 

示例如下。

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

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

Interesting Posts