1. 程式人生 > >socket繫結INADDR_ANY

socket繫結INADDR_ANY

其中INADDR_ANY就是指定地址為0.0.0.0的地址,這個地址事實上表示不確定地址,或“所有地址”、“任意地址”。

一 般情況下,如果你要建立網路伺服器,則你要通知伺服器作業系統:請在某地址 xxx.xxx.xxx.xxx上的某埠 yyyy上進行偵聽,並且把偵聽到的資料包傳送給我。這個過程,你是通過bind()系統呼叫完成的。——也就是說,你的程式要繫結伺服器的某地址,或者 說:把伺服器的某地址上的某端口占為已用。伺服器作業系統可以給你這個指定的地址,也可以不給你。

如果你的伺服器有多個網絡卡,
而 你的服務(不管是在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地址傳送資料了。

為什麼不會重複傳送資料包呢?
答:因為傳送資料包的路由(路徑)是唯一的。如果伺服器不知道在傳送資料的時候應該向哪個地址傳送資料,那麼資料就會被髮送到“預設閘道器”上。

如何選擇傳送資料的路徑呢?
答:依照路由表的要求傳送。

如果路由表的記錄有重複/有衝突呢,這時候如何選擇路徑呢?

答:路由表記錄有優先級別。一般來說,Windows作業系統的路由表記錄,如果是重複的話,以後來加入的記錄為準,而某些作業系統,象linux/FreeBSD是不允許加入重複的路由表記錄的。

如果路由表的記錄有重複/有衝突呢,這時候如何選擇路徑呢?
答:路由表記錄有優先級別。一般來說,Windows作業系統的路由表記錄,如果是重複的話,以後來加入的記錄為準,而某些作業系統,象linux/FreeBSD是不允許加入重複的路由表記錄的;

如 果是專用的路由器,有路由選擇演算法,一般來說,到達網路上的某一點的路徑是可以有很多條的。路由選擇演算法可以確定“最好的一條路徑”,這條路徑要麼是延時 最小的,要麼是通訊費用最低的,要麼是頻寬最高的,要麼是跳點最小的——究竟是如何選擇,就看路由器的管理員如何配置了。