不可不知的Socket和TCP连接过程
当未完成连接队列满了,监听者被阻塞不再接收新的连接请求,并通过select()/poll()等待两个队列触发可写事件。当已完成连接队列满了,则监听者也不会接收新的连接请求,同时,正准备移入到已完成连接队列的动作被阻塞。在Linux 2.2以前,listen()函数有一个backlog的参数,用于设置这两个队列的最大总长度,从Linux 2.2开始,这个参数只表示已完成队列的最大长度,而/proc/sys/net/ipv4/tcp_max_syn_backlog则用于设置未完成队列的最大长度。/proc/sys/net/core/somaxconn则是硬限制已完成队列的最大长度,默认为128,如果backlog大于somaxconn,则backlog会被截断为等于该值。 当连接已完成队列中的某个连接被accept()后,表示TCP连接已经建立完成,这个连接将采用自己的socket buffer和客户端进行数据传输。这个socket buffer和监听套接字的socket buffer都是用来存储TCP收、发的数据,但它们的意义已经不再一样:监听套接字的socket buffer只接受TCP连接请求过程中的syn和ack数据;而已建立的TCP连接的socket buffer主要存储的内容是两端传输的"正式"数据,例如服务端构建的响应数据,客户端发起的Http请求数据。 netstat命令的Send-Q和Recv-Q列表示的就是socket buffer相关的内容,以下是man netstat的解释。 Recv-Q Established: The count of bytes not copied by the user program connected to this socket. Listening: Since Kernel 2.6.18 this column contains the current syn backlog.Send-Q Established: The count of bytes not acknowledged by the remote host. Listening: Since Kernel 2.6.18 this column contains the maximum size of the syn backlog. 对于监听状态的套接字,Recv-Q表示的是当前syn backlog,即已完成队列中当前的连接个数,Send-Q表示的是syn backlog的最大值,即已完成连接队列的最大连接限制个数; 对于已经建立的tcp连接,Recv-Q列表示的是recv buffer中还未被用户进程拷贝走的数据大小,Send-Q列表示的是远程主机还未返回ACK消息的数据大小。之所以区分已建立TCP连接的套接字和监听状态的套接字,就是因为这两种状态的套接字采用不同的socket buffer,其中监听套接字更注重队列的长度,而已建立TCP连接的套接字更注重收、发的数据大小。 [root@xuexi ~]# netstat -tnlActive Internet connections (only servers)Proto Recv-Q Send-Q Local Address Foreign Address State tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN tcp6 0 0 :::80 :::* LISTEN tcp6 0 0 :::22 :::* LISTEN tcp6 0 0 ::1:25 :::* LISTEN[root@xuexi ~]# ss -tnlState Recv-Q Send-Q Local Address:Port Peer Address:PortLISTEN 0 128 *:22 *:* LISTEN 0 100 127.0.0.1:25 *:* LISTEN 0 128 :::80 :::* LISTEN 0 128 :::22 :::* LISTEN 0 100 ::1:25 :::* 注意,Listen状态下的套接字,netstat的Send-Q和ss命令的Send-Q列的值不一样,因为netstat根本就没写上已完成队列的最大长度。因此,判断队列中是否还有空闲位置接收新的tcp连接请求时,应该尽可能地使用ss命令而不是netstat。 2.3.2 syn flood的影响 (编辑:西安站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |