我最近遇到了使用libev描述TCP服务器客户端的this blog post。服务器使用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
,但没有给出任何理由或解释。
那实际上是做什么的?它是否尝试所有接口,直到找到端口可用于连接的接口?这会发生什么顺序?
感谢您的回答!
答案 0 :(得分:4)
您的问题似乎并非真正关于&#34;客户端&#34;,但关于bind
vs connect
。
INADDR_ANY
可以在客户端和服务器上与bind
明智地一起使用。与connect()
一起使用是毫无意义的,应该导致连接失败。
答案 1 :(得分:3)
这是nos在评论中提供的答案。如果nos回来并将其作为答案发布,我将标记为nos&#39;发布作为答案并删除此答案。
INADDR_ANY通常定义为0.即IP地址0.0.0.0。 RFC 1122表示这意味着&#34;这个主机在这个网络上#34;。 linux IP stack似乎只是将它路由到loopback接口。 (例如试试 ping 0.0.0.0甚至只是ping 0)。我说作者写错字了 应该使用INADDR_LOOPBACK。
答案 2 :(得分:0)
在客户端,使用INADDR_ANY是多余的,但我已经看到了一些代码,我想这是为了完整性&#39;。如果要强制使用特定接口,则可以在客户端指定接口,例如在多宿主机器中。
绑定到客户端的端口也不常见。让系统找到可用端口通常是一个更好的主意,否则程序可能会失败,因为端口正好被客户端或服务器使用。
答案 3 :(得分:0)
有一个古老的BSD约定,连接到INADDR_ANY意味着您要连接到回送网络。 linux网络代码明确支持此功能(在this file中搜索INADDR_ANY)。我不知道还有哪些其他操作系统支持或不支持它。