关闭tcp连接时有时发送FIN有时发送RST

博客探讨了在HTTP请求中,发送数据后设置1s超时,有时关闭连接发送FIN,有时发送RST的原因。这与TCP的接收缓冲区的三个队列——receive、backlog和prequeue有关。当recv()阻塞时,数据可能完全进入预存队列(发送FIN),也可能未完全接收(发送RST)。文章引用了相关技术博客作为参考。
摘要由CSDN通过智能技术生成

使用http 发送同一个包,sleep 20 秒后再读取数据,htpp设置1s的超时时间,超时后会关闭socket ,可是有时发送RST,有时发送FIN,如下图:

 

后来google 了一把,发现 tcp 的接受缓冲区的数据到 用户态,中间会有三个队列:

  • receive队列是真正的接收队列,操作系统收到的TCP数据包经过检查和处理后,就会保存到这个队列中。
  • backlog是“备用队列”。当socket处于用户进程的上下文时(即用户正在对socket进行系统调用,如recv),操作系统收到数据包时会将数据包保存到 backlog队列中,然后直接返回。
  • prequeue是“预存队列”。当socket没有正在被用户进程使用时,也就是用户进程调用了read或者recv系统调用,但是进入了睡眠状态时,操作系统直接将收到的报文保存在 prequeue中,然后返回。

正常来说 TCP 收消息过程会涉及三个队列:

  1. backlog:  sk->sk_backlog
  2. prequeue: tp->ucopy.prequeue
  3. receive:        sk->sk_receive_queue

go程序调用send() 后,recv() 就处于阻塞状态,所以数据会进入Prequeue中,而此时由于超时时间到时,recv()没有执行完成,

有时一个消息可以全部进入Prequeue,这时缓冲区中没有数据,所以关闭时,发送的是FIN

有时不能全部进入Prequeue,这时缓冲区中还有部分数据,所以关闭是,发送的是RST; 

参考:

https://ylgrgyq.github.io/2017/08/01/linux-receive-packet-3/

https://www.cnblogs.com/chenny7/p/5067826.html

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值