套接字 - 在客户端使用 INADDR_ANY

Posted

技术标签:

【中文标题】套接字 - 在客户端使用 INADDR_ANY【英文标题】:Sockets - Using INADDR_ANY on client side 【发布时间】:2014-04-18 13:05:47 【问题描述】:

我最近遇到了this blog post,它描述了一个使用 libev 的 TCP 服务器客户端。服务器使用INADDR_ANY 绑定到我熟悉的接口。但是,我很惊讶地在客户端代码中看到INADDR_ANY。客户端代码上的相关代码如下:

// Create client socket
if( (sd = socket(PF_INET, SOCK_STREAM, 0)) < 0 )

  perror("socket error");
  return -1;


bzero(&addr, sizeof(addr));

addr.sin_family = AF_INET;
addr.sin_port = htons(PORT_NO);
addr.sin_addr.s_addr = htonl(INADDR_ANY);

// Connect to server socket
if(connect(sd, (struct sockaddr *)&addr, sizeof addr) < 0)

  perror("Connect error");
  return -1;

特别是我对这条线感兴趣:

addr.sin_addr.s_addr = htonl(INADDR_ANY);

在服务器端,我知道INADDR_ANY 会将端口绑定到所有可用接口,但我不确定这在客户端有什么意义。最后,客户端将需要在特定接口上进行连接。之前我一直指定IP地址或者使用INADDR_LOOPBACK

The Linux IP man page 没有谈到在客户端使用INADDR_ANY。我确实找到了another Stack Overflow post here,它说OP 应该在客户端使用INADDR_ANY,但没有给出任何理由或解释。

那么这实际上在做什么?它是否会尝试所有接口,直到找到一个可用于连接的端口?这是按什么顺序发生的?

感谢您的回答!

【问题讨论】:

相关:***.com/questions/11982562/… post you have cited 并没有像您在这里所说的那样说任何事情。 【参考方案1】:

在客户端,使用 INADDR_ANY 是多余的,但我已经看到了一些代码,我猜它是为了“完整性”。如果要强制使用特定接口,可以在客户端指定接口,例如在多宿主机器中。

在客户端绑定到端口也是不常见的。通常最好让系统找到可用端口,否则程序可能会失败,因为该端口恰好正在被客户端或服务器使用。

【讨论】:

问题中的用法与客户端bind() 无关,我同意这种用法很少见但很明智。问题是将INADDR_ANY 传递给connect()【参考方案2】:

您的问题似乎不是关于“客户端”,而是关于bindconnect

INADDR_ANY 可以在客户端和服务器上与bind 一起使用。将它与connect() 一起使用是没有意义的,应该会导致连接失败。

【讨论】:

然而,我已经测试了博客条目中的代码并且它可以工作。如果您没有通过addr.sin_addr.s_addr 明确声明要使用的接口,套接字 API 如何知道尝试通过哪个接口进行连接? INADDR_ANY 通常定义为 0。即 IP 地址 0.0.0.0。 RFC 1122 说这意味着“这个网络上的这个主机”。 linux IP 堆栈似乎只是将其路由到环回接口。 (例如,试试ping 0.0.0.0 甚至只是ping 0)。我会说作者打错了,应该使用 INADDR_LOOPBACK。 @nos:嗯,某些版本的 Linux IP 堆栈正在这样做。但这不是标准的,其他操作系统确实会返回错误。 nos - 这确实是我一直在寻找的答案。如果您将评论移至答案,我会将其标记为此类。【参考方案3】:

这是 nos 在评论中提供的答案。如果 nos 回来并把它作为答案发布,我会将 nos 的帖子标记为答案并删除。

INADDR_ANY 通常定义为 0。即 IP 地址 0.0.0.0。 RFC 1122 说这意味着“这个网络上的这个主机”。 linux IP 堆栈似乎只是将其路由到环回接口。 (例如尝试 ping 0.0.0.0 甚至只是 ping 0)。我想说作者打错字了 应该使用 INADDR_LOOPBACK。

【讨论】:

【参考方案4】:

有一个旧的 BSD 约定,连接到 INADDR_ANY 意味着您想要连接到环回网络。 linux 网络代码明确支持这一点(在this file 中搜索 INADDR_ANY)。我不知道其他操作系统支持或不支持它。

【讨论】:

以上是关于套接字 - 在客户端使用 INADDR_ANY的主要内容,如果未能解决你的问题,请参考以下文章

套接字 - 在客户端使用 INADDR_ANY

如何使用相同的本地端口打开两个 udp 客户端套接字

使用 Java 在服务器应用程序和 Matlab 客户端之间进行套接字通信

如何使用套接字(socket.io)在 NodeJS 中找到客户端的响应时间(延迟)?

在客户端监听套接字(Android)

TCP 客户端异步套接字回调