我有一个 HTTP web 服务,有时连接设置会以一种奇怪的方式失败:
- 客户端发送 SYN 数据包
- 服务器发送 SYN,ACK 答复
- 客户端以 RST 响应
在什么情况下客户端系统会决定用 RST 数据包回复?我可以想象当 SYN、ACK 包含例如不正确的序列号时会发生这种情况(但这似乎不适用于我的情况 - 序列号看起来没问题)。所以我对客户端在收到 SYN、ACK 数据包后发送 RST 数据包的详尽情况列表感兴趣。
具体来说,客户端应用程序代码(使用 Linux 下的普通 BSD 样式套接字 API)是否有可能引发此 RST 数据包,例如close()
在三次握手仍在进行时通过调用?
答案1
最后总结一下:这个问题是我的代码(在客户端)中的一个愚蠢的错误。
在这种情况下,客户端使用非阻塞套接字,因此connect()
调用将立即返回,而内核则继续等待来自服务器的 SYN、ACK 数据包。不幸的是,客户端代码非常没有耐心:如果几百毫秒后仍未建立连接,客户端将调用close()
套接字。
在极少数情况下,来自服务器的 SYN、ACK 数据包在通过网络时会延迟几百毫秒。当延迟的回复最终到达客户端主机时,内核会发现套接字已关闭,并将 SYN、ACK 回复视为属于无效套接字。这就是为什么它会向服务器回复 RST 数据包的原因。
因此,是的,应用程序代码(使用 Linux 下的普通 BSD 样式套接字 API)有可能导致此 RST 数据包:通过使用非阻塞套接字并在三方握手仍在进行时关闭连接。
答案2
我用了普惠公司并得到原因:
0xffff8bf389d5e600 1 [<empty>] kfree_skb_reason(SKB_DROP_REASON_NO_SOCKET)