注意:tcp的三次握手和四次分手都是在内核空间完成的。
仅讨论连接队列满了的情况,网络不通等情况造出的连接拒绝不在这次讨论范围。
服务端程序启动,会创建一个监听Socket,当客户端发送请求连接时,监听Socket会fork()出一个连接Socket与客户端建立连接。当客户端与服务端完成tcp三次握手之后,会将连接放入accept queue 中,应用服务负责消费连接。
当 “已建立成功(状态为ESTABLISHED),但,尚未交付给应用的” tcp连接的数量 ,即 RECV-Q 的数量超过 SEND-Q+1 的时候,新来的连接会被拒绝(connection refused)
netstat -antp
命令
ss -ln
netstat和ss 都
Recv-Q:“OS持有的,尚未交付给应用的 数据的 字节数”
Send-Q:“已经发送给对端应用,但,对端应用尚未ack的 字节数。此时,这些数据依然要由OS持有”
ss的Recv-Q:“已建立成功(状态为ESTABLISHED),但,尚未交付给应用的” tcp连接的数量。
该值最大为:Send-Q+1,即:min(backlog, somaxconn)+1。
之所以加1,是因为OS内核在判断队列是否已满时,用的是>(应该用>=),这导致当已创建成功的连接数量正好等于min(backlog, somaxconn)时,还会再多创建一个tcp连接,最终结果就是:min(backlog, somaxconn)+1
ss的Send-Q:listen时,backlog的大小。其值为min(backlog, somaxconn)
netstat的Recv-Q :含义同ss的Recv-Q
netstat的Send-Q: 尽管文档中说是"Since Kernel 2.6.18 this column contains the maximum size of the syn backlog",但,实验中看不出来
参考:https://blog.csdn.net/iceman1952/article/details/109014798
防止丢包。当发送ACK之后,等待是否还有FIN发送过来,如果没有了,就说明正常收到ACK了。