listen函數,從英語上了解就是一個"聽"函數,實際上它也就是這個意思。我們來看unix網絡程式設計這本書是怎樣對它的解釋:listen函數把一個未連接配接的套接字轉換成一個被動套接字,訓示核心應該接受指向該套接字的連結請求。該函數有2個參數,第一個我就不說了,第二參數規定了核心為相應套接字排隊的最大連接配接個數。隻看這些理論搞的人稀裡糊塗,我們還是來測一下。
請注意上面的服務端中,我是沒有調用accept函數的,直接調用getchar()了,跑起來。
服務度開啟,然後新打開一個視窗開啟用戶端。
檢視網絡:
看,已經建立起一個連接配接了。但是我們沒有調用accept函數,連接配接還是建立起來了,這說說明accept函數和TCP三向交握沒啥關系,這也是一個知識盲點。好,在開啟一個新視窗運作用戶端,檢視網絡狀态。(新開視窗運作用戶端同上,這裡就不用代碼示範了)
看,又建立起一個連接配接。在運作一個用戶端,看網絡狀态。
當第三個用戶端連接配接進來的時候,出現了一個SYN_RECV,這标明第三個用戶端沒有與服務端建立連接配接。我們listen函數設定的監聽隊列為1,那麼監聽隊列塞了2個之後就沒有往裡面塞了。這下大概懂了listen函數第二個參數的意義了吧,當參數為1的時候隻能監聽2個套接字,這應該是從0開始數的。為什麼是大概呢?其實unix網絡程式設計上是這樣說的:listen函數的第二個參數是ESTABLISHED和SYN_RECV之和,隻是在監聽隊列沒有滿的情況下,SYN_RECV狀态不容易重制。這時候在服務度輸入一個字元會有啥效果呢?答案告訴你,就是那個SYN_RECV狀态變成ESTABLISHED了,這也是 accept函數的作用。accept函數會将已完成連接配接隊列中的對頭項傳回給程序,是以SYN_RECV變成ESTABLISHED了。這個現象留給大家去實踐一下吧,隻有自己實踐出來的東西才是自己的。