在我用 SYN + ACK 数据包回复 SYN 数据包后,开始从客户端套接字获取 RST 数据包

STARTED getting RST packet from client socket after I replied SYN packet with SYN + ACK packet

我正在创建简单的 TCP 模拟程序,它可以充当 IP 上的简单 TCP 服务器,问题出在我收到 SYN 数据包时编写的代码中,--> 我在我的程序中制定了所有响应数据包服务器并创建响应数据包并使用 SYN+ACK 数据包进行回复。

但是在我用 SYN+ACK 数据包回复后,我立即从客户端套接字收到 RST 数据包。我不知道我的 TCP 或某些 header 有什么问题使我的客户端套接字只是用 RST 数据包回复我的 SYN+ACK 数据包。

我在网上读到 RST 数据包,它说 RST 在主机上收到有两个原因,但可能还有更多原因

There are a few circumstances in which a TCP packet might not be expected; the two most common are:

    The packet is an initial SYN packet trying to establish a connection to a server port on which no process is listening.
    The packet arrives on a TCP connection that was previously established, but the local application already closed its socket or exited and the OS closed the socket.

所以我想知道在我的案例中给出的原因是什么。

当我在程序 IP 套接字上收到 SYN 数据包时

0000   45 00 00 3c 81 37 40 00 40 06 24 11 c0 a8 0a 14
0010   c0 a8 0a 0f ba 50 00 50 15 1a 68 41 00 00 00 00
0020   a0 02 fa f0 a3 ce 00 00 02 04 05 b4 04 02 08 0a
0030   de d7 fc f8 00 00 00 00 01 03 03 07

我用SYN+ACK包回复。我的 TCP 数据包看起来像这样

0000   45 00 00 28 00 64 40 00 40 06 a4 f8 c0 a8 0a 0f
0010   c0 a8 0a 14 00 50 ba 50 00 01 00 00 15 1a 68 41
0020   50 12 fa f0 e7 70 00 00

所以 TCP 中的字段就像上面的 20 (IP header)+20 (TCP header) 字节的数据包 (SYN+ACK) 用于 SYN+ACK 从我的代码回复到客户端插座。但是我的客户端没有开始从客户端发送数据,而是开始发送 RST 数据包,在我的代码中,我在将 SYN + ACK 数据包从我的代码发送到客户端套接字后立即收到 RST 数据包。

但是在上面的 headers 值中我得到 RST 数据包(重置数据包)而不是从客户端或至少我的客户端套接字获取一些数据的是什么 [connect()] 函数调用成功?如何让我的客户端发送的这个 RST 数据包消失,以便我的客户端最终开始发送数据并且我的服务器代码开始获取数据?我做错了什么?

我没有发现这个数据包有什么本质上的错误,但是这个数据包必须在 SYN 的上下文中获取。 SYN+ACK中ACK的期望序号是SYN的序号(ISN,即初始序号)加1.

但是,ACK 不是 ISN+1,而只是收到的 SYN 的 ISN。这意味着 SYN+ACK 出现故障,从而导致 RST。

发送 RST 的一般原因是接收方找不到套接字,应该归因于传入数据包。

常见情况包括:

  • 不匹配的端口:端口对
  • 没有打开的套接字
  • mistmatched sequence numbers: ACK number 不正确,或者 ACK number 不适合发送方的window(这里的发送方是收到 ACK 的一方,因为ACK 是对发件人发送内容的回应)

根据 TCP 规范,设置了 SYN(以及 FIN)标志的数据包通过加一的 ACK 编号进行确认,也就是说,好像这些标志占用了一个数据字节。


同时考虑收到的SYN和发送的SYNACK,可以看出,SYN中的序列号是15 1a 68 41,SYNACK中的ACK号也是15 1a 68 41,不是SYN + 1应该是。

P.S.: TCP 报头的结构可以在例如 wikipedia. An explanation how to match packet bytes to header fields can be found in . Also, an illustration of sender window can be found here.

中找到