INADDR_ANY就是指定地址爲0.0.0.0的地址,這個地址事實上表示不肯定地址,或「全部地址」、「任意地址」。 通常來講,在各個系統中均定義成爲0值。linux
例如MontiVista Linux中在/usr/include/netinet/in.h定義爲:算法
/* Address to accept any incoming messages. */
#define INADDR_ANY ((in_addr_t) 0x00000000)緩存
通常狀況下,若是你要創建網絡服務器 應用程序,則你要通知服務器操做系統:請在某地址 xxx.xxx.xxx.xxx上的某端口 yyyy上進行偵聽,而且把偵聽到的數據包發送給我。這個過程,你是經過bind()系統調用完成的。——也就是說,你的程序要綁定服務器的某地址,或者 說:把服務器的某地址上的某端口占爲已用。服務器操做系統能夠給你這個指定的地址,也能夠不給你。
如 果你的服務器有多個網卡(每一個網卡上有不一樣的 IP地址),而你的服務(不論是在udp端口上偵聽,仍是在tcp端口上偵聽),出於某種緣由:多是你的服務器操做系統可能隨時增減IP地址,也有可能 是爲了省去肯定服務器上有什麼網絡端口(網卡)的麻煩 —— 能夠要在調用bind()的時候,告訴操做系統:「我須要在 yyyy 端口上偵聽,因此發送到服務器的這個端口,不論是哪一個網卡/哪一個IP地址接收到的數據,都是我處理的。」這時候,服務器程序則在0.0.0.0這個地址上 進行偵聽。例如:
Proto Recv-Q Send-Q Local Address Foreign Address (state)
……
udp4 0 0 *.7913 *.*
udp4 0 0 *.7911 *.*
tcp4 0 0 *.ftp *.* LISTEN
……
……
以上這些是網絡偵聽的狀況,其中Local Address 爲 「*.ftp」、「*.7911」等,表明了服務程序綁定了服務器的全部網卡。
好了,你明白了偵聽INADDR_ANY是什麼意思了,那麼,個人服務器有N個IP地址,會不會收到重複的數據包?收到數據包後,是否是會重複回覆客戶端呢?
答案是:不會收到重複的數據包,也不會重複發送數據。
爲 什麼呢?由於路由的關係,從客戶端來的IP包只可能到達其中一個網卡。同時在服務器進程發送數據時,操做系統根據自身維護着的路由表,決定IP數據包應該 c從哪個outbound的gateway向目標端發送。根據gateway選擇的不一樣,也就決定了從哪個網卡/哪一個IP地址發送。
爲何不會接收到重複的數據包呢?
答:由於客戶端只向你的服務器上的惟一一個IP地址發送數據了。
爲何不會重複發送數據包呢?
答:由於發送數據包的路由(路徑)是惟一的。若是服務器不知道在發送數據的時候應該向哪一個地址發送數據,那麼數據就會被髮送到「默認網關」上。
如何選擇發送數據的路徑呢?
答:依照路由表的要求發送。
若是路由表的記錄有重複/有衝突呢,這時候如何選擇路徑呢?
答:路由表記錄有優先級別。通常來講,Windows操做系統的路由表記錄,若是是重複的話,之後來加入的記錄爲準,而某些操做系統,象linux/FreeBSD是不容許加入重複的路由表記錄的;
若是是專用的路由器,有路由選擇算法,通常來講,到達網絡上的某一點的路徑是能夠有不少條的。路由選擇算法能夠肯定「最好的一條路徑」,這條路徑要麼是延時最小的,要麼是通信費用最低的,要麼是帶寬最高的,要麼是跳點最小的——到底是如何選擇,就看路由器的管理員如何配置了。服務器
對於客戶端若是綁定 INADDR_ANY,狀況相似。對於TCP而言,在connect()系統調用時將其綁頂到一具體的IP地址。選擇的 依據是該地址所在子網到目標地址是可達的(reachable). 這時經過getsockname()系統調用就能得知具體使用哪個地址。對於UDP而言, 狀況比較特殊。即便使用connect()系統調用也不會綁定到一具體地址。這是由於對UDP使用connect()並不會真正向目標地址發送任何創建連 接的數據,也不會驗證到目標地址的可達性。它只是將目標地址的信息記錄在內部的socket數據結構之中,共之後使用。只有當調用 sendto()/send()時,由系統內核根據路由表決定由哪個地址(網卡)發送UDP packet.網絡
P.S.數據結構
-----------------------------------------------------------------------------socket
在IP層中有一個路由表:
在MSDOS窗口能夠運行命令:netstat -r
來顯示路由表。根據路由表的條目從指定的網卡發送數據。
ARP緩存用:arp -a
來顯示。
一般以太網幀的目的MAC地址,是下一跳的MAC地址。tcp
-----------------------------------------------------------------------------spa