2014-03-13 167 views
3

我最近遇到this blog post,它描述了一个使用libev的TCP服务器客户端。服务器使用INADDR_ANY绑定到我熟悉的界面。然而,我很惊讶在客户端代码中看到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; 
} 

具体我interesed在该行:

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

相关:http://stackoverflow.com/questions/11982562/socket-connect-to-0-0-0-0-windows-vs-mac –

回答

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。

0

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

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

+1

问题中的用法不是与客户端'bind()',我认为这很少见,但很明智。问题是将'INADDR_ANY'传递给'connect()'。 –

4

看起来你的问题并不是真的关于“客户端”,而是关于bindconnect

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

+0

然而,我已经测试了博客条目中的代码,它的工作原理。如果你没有明确声明通过'addr.sin_addr.s_addr'使用接口,套接字API怎么知道尝试连接的接口呢? –

+5

INADDR_ANY通常定义为0.这就是IP地址0.0.0.0。RFC 1122表示,这意味着“此网络上的此主机”。 Linux IP堆栈似乎只是将其路由到回送接口。 (例如,尝试“ping 0.0.0.0”或甚至只是“ping 0”)。我会说作者犯了一个错字,并且应该使用INADDR_LOOPBACK。 – nos

+1

@nos:嗯,某些版本的Linux IP堆栈正在这样做。但这不是标准的,其他操作系统确实会返回错误。 –