INADDR_ANY

INADDR_ANY

INADDR_ANY就是指定地址為0.0.0.0的地址,這個地址事實上表示不確定地址,或“所有地址”、“任意地址”。 一般來說,在各個系統中均定義成為0值。

定義

例如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數據包應該從哪一個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.

-----------------------------------------------------------------------------

在IP層中有一個路由表:

在MSDOS視窗可以運行命令:netstat -r

來顯示路由表。根據路由表的條目從指定的網卡傳送數據。

ARP快取用:arp -a

來顯示。

通常乙太網幀的目的MAC地址,是下一跳的MAC地址。

-----------------------------------------------------------------------------

相關詞條

熱門詞條

聯絡我們