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

vanimi 发布于 2018-02-02 c 最后更新 2018-02-02 11:40 723 浏览

我一直有问题让C的套接字API在C++中正常工作。具体来说,虽然我包含了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”,第5.16行:CCN5274(S)“AF_INET”的名称查找没有找到声明。 (I)编译文件./inet.C失败。目标文件未创建。 sys/sockets.h的检查确实包括了我所需要的定义,就我所知,它并没有被任何#ifdef语句阻塞。 但是我注意到它包含以下内容:
#ifdef __cplusplus
  extern "C" {
#endif
它基本上封装了整个文件。不知道是否重要。
已邀请:

eomnis

赞同来自:

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

#include <sys/socket.h>
int
main()
{
    return AF_INET;
}
所以我认为z/OS在这里可能是一个复杂的因素,然而,因为我以前从来没有使用过z/OS,更不用说编程了,所以我不能说这是明确的。 :-P

eomnis

赞同来自:

extern "C"事情非常重要。如果头文件没有头文件(除非是C++头文件),则必须将#include加上:

extern "C" {
#include <sys/socket.h>
// include other similarly non-compliant header files
}
基本上,只要C++程序想要链接到基于C的工具,extern "C"就非常重要。实际上,这意味着在外部引用中使用的名称不会像通常的C++名字那样被破坏。 Reference.

id_aut

赞同来自:

免责声明:我不是一个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;
};
然后有方法来打开,关闭和发送数据包的插座。 例如,公开呼叫可能看起来像这样:
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;
}

nin

赞同来自:

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

nvelit

赞同来自:

所以试试

#define _OE_SOCKETS
在包含sys/socket.h之前

xet

赞同来自:

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

iqui

赞同来自:

请参阅z/OS XL C/C++编程指南中的使用z/OS UNIX系统服务套接字部分。确保你包含必要的头文件并使用适当的#defines。 多年来,文档的链接已经发生了变化,但您应该可以通过ibm.com找到Support & Downloads section的当前位置并按标题搜索文档,从而轻松找到它。

vsit

赞同来自:

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

  • z/OS V1R11.0 XL C/C++ Programming Guide
  • z/OS V1R11.0 XL C/C++ Run-Time Library Reference
  • IBM的出版物一般都很好,但是您需要习惯他们的格式,以及知道在哪里寻找答案。你会经常发现你想要使用的功能是由“功能测试宏”来保护的, 你应该问你的友好的系统程序员在你的系统上安装XL C/C++ Run-Time Library Reference: Man Pages 。然后你可以做一些事情,比如“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);
    
    伯克利插座
    #define _OE_SOCKETS
    #include <sys/types.h>
    #include <sys/socket.h>
    int connect(int socket, struct sockaddr *address, int address_len);
    

det

赞同来自:

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

 -D_OE_SOCKETS
示例如下。
 bash-2.03$ c89 -D_OE_SOCKETS [filename].c
有关更多信息,请参见“z/OS XLC/C++用户指南”中的“C89选项”。