2013年2月9日 星期六

listen()於linux的實作

相信這已經是很多人相當熟悉的function call,根據man page,有一個參數就是backlog的個數,乃至於一些kernel的引用
The behavior of the backlog argument on TCP sockets changed with Linux 2.2. Now it specifies the queue length for completely established sockets waiting to be accepted, instead of the number of incomplete connection requests. The maximum length of the queue for incomplete sockets can be set using /proc/sys/net/ipv4/tcp_max_syn_backlog. When syncookies are enabled there is no logical maximum length and this setting is ignored. See tcp(7) for more information.
但是比較明確表示有可能是有其他解釋的是posfix的定義
The backlog argument provides a hint to the implementation which the implementation shall use to limit the number of outstanding connections in the socket's listen queue.
可以試驗使用底下的程式建立server

...
sockfd = socket(AF_INET, SOCK_STREAM, 0);
...

listen(sockfd, 3);
sleep(50);
...

隨便寫個client,會發現在sleep期間,還是可以連上該server 3個connections以上,這是發生了啥麼事情!?
事實上只是一個實作上的方式不同,就如同kernel上面人家引述的,linux使用了一個queue來儲存在些incomplete sockets,但是這個queue size卻不等於backlog的參數,因為reqsk_queue_alloc()實作(version 2.6.36)是以2^n在成長,一般最小為16,系統一般的上限為256(int sysctl_max_syn_backlog = 256;)

此外,在richard stevens書中提到兩點,第一點,backlog從來沒有被嚴格的定義過,第二點,backlog不建議設定為0,因為backlog設定為0,將導致他的解釋依照系統實作而定,有些系統是設定為一系統最小backlog數(e.g. 16)

所以說,man page有時候還是跟實作上有差異的,參考就好,果然網路程式真的是博大精深阿

沒有留言:

張貼留言