2014-03-13 166 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堆棧正在這樣做。但這不是標準的,其他操作系統確實會返回錯誤。 –