經過一番折騰,現總結一下listen的參數backlog。
PS:服務端環境:ubuntu12.04。用戶端無所謂:我mac os x 10.7。
先$ man listen看看,裡面有一段話:
If the backlog argument is greater than the value in /proc/sys/net/core/somaxconn, then it
is silently truncated to that value; the default value in this file is 128. In kernels
before 2.4.25, this limit was a hard coded value, SOMAXCONN, with the value 128.
$ sudo vi /proc/sys/net/core/somaxconn可以看linux的SOMAXCONN值,我的是128。修改為256就不錯了貌似。。。
再傳一張圖,unp卷1裡的(注意,下面這圖未完成串連隊列的狀態應該是SYN_RECV,可能人家寫錯了):
好,現在總結下我服務端調用listen的情況:
(注意:不要在同一個機器上測試,我懷疑同一個機器下沒有經曆三向交握。我在ubuntu12.04下同時跑用戶端和服務端程式時就發現無論backlog設為多少,“已完成連結隊列”都一直上漲根本沒有停止,“未完成連結隊列”在10左右搖擺.)
當傳參backlog的值< somaxconn時,已完成連結隊列的數量最多就是backlog的值。未完成連結隊列數量在10左右搖擺。
當傳參backlog的值 >= somaxconn時,已完成連結隊列的數量最多就是somaxconn。未完成連結隊列數量同上。
結論噢:在ubuntu12.04上,backlog的值就是已完成連結隊列的值,此值受限於somaxconn。
最後,給出察看服務端兩隊列的值的指令碼(指令碼裡的4333是我服務端程式的連接埠值):
#!/bin/shecho "已建立連結隊列裡通訊端的數量"while [ "1" = "1" ]donetstat -nat | grep ESTABLISHED | grep 4333 | wc -lsleep 2done
#!/bin/shecho "未建立連結隊列裡通訊端的數量"while [ "1" = "1" ]donetstat -nat | grep SYN_RECV | grep 4333 | wc -lsleep 2done
順便說一下,listen函數不是阻塞式的,它只是告訴核心開啟某連接埠監聽,真正“監聽”的是核心,而不是我們的服務端程式。
listen把第一個參數通訊端轉換成監聽通訊端。