簡單分析一下socket中的bind

2021-07-10 01:15:21 字數 1337 閱讀 1273

在最開始接觸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的現象。

經過驗證netty框架的客戶端在呼叫bind埠號,也是沒有生效,客戶端監聽的埠號也是隨機分配的。

簡單分析一下socket中的bind

在最開始接觸bind的時候,只是在寫基於tcp的server端的時候,知道在listen之前需要先bind一下,用來確保socket能在某個固定的埠監聽。而bind的時候,函式引數中的埠填自己將要繫結的埠就行 而ip位址,需要填本機的ip,但是也可以用乙個巨集inaddr any代替,用這個巨集就可...

簡單的分析一下sencha touch2

最近,sencha touch2.0發布。較之前兩個版本,此次做了不小的改動。因為從機器執行的速度就可以體現出來。之前的sencha touch版本在android客戶端執行速度緩慢,最新的2.0版的,可以說實現了質的飛躍。對於新版的特性,我作出了簡單的總結。首先看一下官網給出的解釋吧 提供原生打包...

簡單介紹一下OGraph

摘要 該引擎的目標在於能夠渲染3d場景,和視覺化複雜網路 並且支援方便的資料介面,遊戲一般的互動體驗。引擎嵌入python為使用者提供api,編寫python 讀取處理資料後提交到渲染介面,即可實時渲染。使用瀏覽器核心向使用者展示ui,管理場景物件樹 物件屬性。使用者也可以自己重新編寫html頁面自...