socket bind 解說

來源:互聯網
上載者:User

在最開始接觸bind的時候,只是在寫基於tcp的server端的時候,知道在listen之前需要先bind一下,用來確保socket能在某個固定的連接埠監聽。而bind的時候,函數參數中的連接埠填自己將要綁定的連接埠就行;而IP地址,需要填原生IP,但是也可以用一個宏INADDR_ANY代替,用這個宏就可以不用尋找原生IP,它就可以代替原生IP。當時只覺得這個INADDR_ANY比較神奇,但是由於當時覺得用起來很方便,也沒出啥問題,也就沒有再深究。

  但是最近在做RTSP伺服器的時候,有種特殊的應用,導致我不得不對bind這個函數仔細地看一下。

  我們知道無論是UDP還是TCP,socket都會與一個本地的IP和連接埠想對應,我們往往把這個IP和連接埠稱之為socket的源地址和源連接埠。當我們作為用戶端利用socket去發送資料時,很少會去考慮這個源地址和源連接埠到底是什麼,我們更關心的是它的目的地址和連接埠。我們往往只有在監聽的時候,才去考慮這個源連接埠,所以我們在監聽的時候會去用bind。當我們bind之後,核心就會將這個socket的源連接埠鎖定到我們設定的連接埠上。但是這就有一個問題,這個bind綁定連接埠,是將本來沒有源連接埠的socket綁定到我們指定的連接埠上,還是將一個已經分配了連接埠的socket重新導向到我們指定的連接埠上呢?

  在《UNIX網路編程》這本書中提到:“如果一個TCP客戶或者伺服器未曾調用bind捆綁一個連接埠,當調用connect或listen時,核心就要為相應的通訊端選擇一個臨時介面。”從這句話中可以判斷出,其實在調用socket函數建立socket時,核心還並未給socket分配源地址和源連接埠。而對於UDP,我猜測在調用sendto發送資料時,在未捆綁連接埠的情況下,核心也會隨機分配連接埠。

  而我遇到的特殊應用要求我在用UDP發送資料之前要告訴對方我的傳送埠,這也就意味著我在sendto之前必須要捆綁連接埠,因此我在發送資料之前就得調用bind函數綁定一下連接埠了。但是我就在想核心既然有隨機分配連接埠的能力,而我需要的也只是讓它綁定一下而不用綁定在固定連接埠的業務,socket中應該能夠提供這種業務。然後果然我發現bind就具備這種能力,當bind的參數中連接埠地址為0的時候,這時候就是由核心分配連接埠。這樣我就不用考慮連接埠地址重複的問題,而放心的把這個問題交給核心處理了。

  就在發現bind的這個機制的同時,我發現其實bind對於源地址也同樣具備這種處理方式,當系統具有多IP(多網卡)的情況,當我們把bind函數中的ip參數置0時,就是由核心自己選擇分配IP。而之前一直覺得很神奇的INADDR_ANY其實一點也不神奇,它的值其實就是0。所以當我們只有單一IP的時候,我們就可以用INADDR_ANY去代替那個單一的IP,因為核心分配的時候只能選擇這一個IP。從而造成了INADDR_ANY就是本機IP的現象。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.