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