[英]Understanding INADDR_ANY for socket programming
我正在嘗試編寫一些套接字,因此在服務器端,我使用htonl(INADDR_ANY)
。 在我理解的范圍內,在我看來,這個函數會生成一個隨機 IP(我說得對嗎?)。 事實上,我想將我的套接字與我的localhost
綁定。 但是如果我運行這個
printf("%d",htonl(INADDR_ANY));
我得到 0 作為返回值。 有人可以帶來一些解釋嗎?
INADDR_ANY
bind()
不會“生成隨機 IP”。 它將套接字綁定到所有可用的接口。
對於服務器,您通常希望綁定到所有接口——而不僅僅是“本地主機”。
如果您只想將套接字綁定到本地主機,則語法為my_sockaddress.sin_addr.s_addr = inet_addr("127.0.0.1");
,然后調用bind(my_socket, (SOCKADDR *) &my_sockaddr, ...)
。
碰巧, INADDR_ANY
是一個常數,恰好等於“零”:
http://www.castaglia.org/proftpd/doc/devel-guide/src/include/inet.h.html
# define INADDR_ANY ((unsigned long int) 0x00000000) ... # define INADDR_NONE 0xffffffff ... # define INPORT_ANY 0 ...
如果您還不熟悉它,我強烈建議您查看 Beej 的套接字編程指南:
由於人們仍在閱讀本文,因此請補充說明:
當一個進程想要接收新的傳入數據包或連接時,它應該使用bind(2)將套接字綁定到本地接口地址。
在這種情況下,只有一個 IP 套接字可以綁定到任何給定的本地(地址、端口)對。 當在綁定調用中指定 INADDR_ANY 時,套接字將綁定到所有本地接口。
當在未綁定的套接字上調用listen(2) 時,該套接字將自動綁定到本地地址設置為 INADDR_ANY 的隨機空閑端口。
當在未綁定的套接字上調用connect(2) 時,該套接字將自動綁定到隨機空閑端口或本地地址設置為 INADDR_ANY 的可用共享端口...
有幾個特殊地址: INADDR_LOOPBACK (127.0.0.1) 總是通過環回設備引用本地主機; INADDR_ANY (0.0.0.0) 表示用於綁定的任何地址...
還:
如果 (sin_addr.s_addr) 字段設置為常量 INADDR_ANY,如 netinet/in.h 中所定義,則調用者請求將套接字綁定到主機上的所有網絡接口。 隨后,來自所有接口(與綁定名稱匹配)的 UDP 數據包和 TCP 連接被路由到應用程序。 當服務器向多個網絡提供服務時,這變得很重要。 通過不指定地址,服務器可以接受為其端口發出的所有 UDP 數據包和 TCP 連接請求,而不管請求到達的網絡接口。
當您不需要將套接字綁定到特定 IP 時使用INADDR_ANY
。 當您在調用bind()
時將此值用作地址時,套接字將接受與機器所有 IP 的連接。
要將套接字與localhost綁定,在調用綁定函數之前,應正確設置 sockaddr_in 結構的 sin_addr.s_addr 字段。 可以通過以下方式獲得適當的值
my_sockaddress.sin_addr.s_addr = inet_addr("127.0.0.1")
或由
my_sockaddress.sin_addr.s_addr=htonl(INADDR_LOOPBACK);
INADDR_ANY
指示偵聽套接字綁定到所有可用接口。 這與嘗試綁定到inet_addr("0.0.0.0")
。 為了完整起見,我還將提到 IPv6 也有IN6ADDR_ANY_INIT ,這與嘗試綁定到 IPv6 套接字的::
地址相同。
#include <netinet/in.h>
struct in6_addr addr = IN6ADDR_ANY_INIT;
另請注意,當您將 IPv6 套接字綁定到IN6ADDR_ANY_INIT
您的套接字將綁定到所有 IPv6 接口,並且也應該能夠接受來自 IPv4 客戶端的連接(盡管 IPv6 映射地址)。
INADDR_ANY 是一個常量,在 value 中包含 0。 僅當您想從不關心 ip-add 的所有活動端口進行連接時才使用。 所以如果你想連接任何特定的 ip 你應該提到像 my_sockaddress.sin_addr.s_addr = inet_addr("192.168.78.2")
當你有一個服務器時,你創建一個套接字,然后將它綁定到一個 IP 和端口,這為套接字提供了一種基於唯一的套接字類型、地址族、IP 和端口進行識別的唯一方式。 然后使用listen() 將套接字設置為服務器模式,然后執行accept(),它等待一個連接,該連接將具有目標參數的入站數據包,這些數據包會在該套接字上排隊。
當你有一個客戶端時,你創建一個套接字,然后將套接字連接()到遠程 IP 和端口,如果它還沒有被綁定,它也會將 0.0.0.0 和一個隨機未使用的臨時端口綁定到套接字使用 bind(INADDR_ANY, 0) 到 IP 和端口。 connect() 連接時返回,並使用 IP 和端口作為出站數據包中的源地址,其中 0.0.0.0 始終由操作系統替換為當前內部 IP,然后您使用 sendall 發送應用程序數據。
INADDR_ANY 比以編程方式獲取計算機當前的內部 IP 更快,該 IP 可能隨時更改,並且端口上將不再接收數據包,但它們仍會在 0.0.0.0 上接收,因為它是任何地址。
請注意,套接字可以綁定到 0.0.0.0,但不能綁定到端口 0,因為它是一個通配符,可以為套接字提供一個隨機的臨時端口,因此當您使用 bind(INADDR_ANY, 0) 時,它綁定到 0.0.0.0 和一個隨機臨時端口。
#include <arpa/inet.h>
.
.
tcpsock.sin_addr.s_addr = inet_addr("192.168.1.2")
為我工作
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.