經過一番折騰,現總結一下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/sh echo "已建立連結隊列里套接字的數量" while [ "1" = "1" ] do netstat -nat | grep ESTABLISHED | grep 4333 | wc -l sleep 2 done
#!/bin/sh echo "未建立連結隊列里套接字的數量" while [ "1" = "1" ] do netstat -nat | grep SYN_RECV | grep 4333 | wc -l sleep 2 done
順便說一下,listen函數不是阻塞式的,它只是告訴內核打開某端口監聽,真正“監聽”的是內核,而不是我們的服務端程序。
listen把第一個參數套接字轉換成監聽套接字。
