173

我在让 C 套接字 API 在 z/OS 上的 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", 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

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

4

9 回答 9

95

随身携带一份 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);
于 2009-09-18T11:17:01.933 回答
44

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

#include <sys/socket.h>

int
main()
{
    return AF_INET;
}

所以我对此的看法是 z/OS 可能是这里的复杂因素,然而,因为我以前从未使用过 z/OS,更不用说在其中编程了,所以我不能明确地说出来。:-P

于 2008-08-01T12:22:40.797 回答
38

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

多年来,该文档的链接发生了变化,但您应该能够通过在ibm.com上找到Support & Downloads 部分的当前位置并按标题搜索文档来轻松访问它。

于 2009-05-15T05:27:09.057 回答
31

所以试试

#define _OE_SOCKETS

在包含 sys/socket.h 之前

于 2008-09-21T12:37:01.023 回答
31

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

看看这个页面:
编译和链接 z/VM C Sockets Program

于 2008-10-11T00:38:49.903 回答
24

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

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

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

于 2008-08-01T13:40:16.443 回答
24

您可能想看看cpp-sockets,一个用于套接字系统调用的 C++ 包装器。它适用于许多操作系统(Win32、POSIX、Linux、*BSD)。我认为它不适用于 z/OS,但您可以查看它使用的包含文件,并且您将拥有许多在其他操作系统上运行良好的测试代码示例。

于 2008-09-07T08:21:50.157 回答
19

免责声明:我不是 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;
}
于 2008-08-29T18:56:19.723 回答
18

使用以下 c89 标志:

 -D_OE_SOCKETS

例子:

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

有关更多信息,请查看 z/OS XLC/C++ 用户指南中的 c89 选项。

于 2011-04-11T18:59:23.960 回答