为什么 TCP 请求数据包包含 ACK 标志?

为什么 TCP 请求数据包包含 ACK 标志?

我对低水平还很陌生TCP,正在尝试tcpdump使用简单的套接字服务器和客户端程序。

服务器和客户端都遵循这两个步骤。

  1. 服务器与客户端建立连接。
  2. 客户端发送一个字符串消息。

以下是 的输出tcpdump

$ tcpdum -i lo

20:47:39.494935 IP localhost.38706 > localhost.5000: Flags [S], seq 2723581943, win 43690, options [mss 65495,sackOK,TS val 425070729 ecr 0,nop,wscale 7], length 0
20:47:39.494952 IP localhost.5000 > localhost.38706: Flags [S.], seq 2339154834, ack 2723581944, win 43690, options [mss 65495,sackOK,TS val 425070729 ecr 425070729,nop,wscale 7], length 0
20:47:39.494964 IP localhost.38706 > localhost.5000: Flags [.], ack 1, win 342, options [nop,nop,TS val 425070729 ecr 425070729], length 0 
20:47:49.471589 IP localhost.38706 > localhost.5000: Flags [P.], seq 1:5, ack 1, win 342, options [nop,nop,TS val 425073223 ecr 425070729], length 4
20:47:49.471625 IP localhost.5000 > localhost.38706: Flags [.], ack 5, win 342, options [nop,nop,TS val 425073223 ecr 425073223], length 0

前三个数据包用于握手,接下来的两个数据包用于客户端请求消息。但是,我想知道为什么客户端请求数据包包含ACK标志([P.]),我认为这是没有任何数据包需要 ACK 的请求的第一条消息。

我认为ACK应该意味着它成功接收了一些数据包。 中的 ACK 是什么[P.].中的 ACK 是什么tcpdump

答案1

它正在再次确认 SYN 数据包。

在 TCP 中,就序列号的计算而言,SYN 和 FIN 位被视为单个字节。并且它们的确认方式几乎相同。这就是为什么您会看到ack 1而不是ack 0

在您的流程中,第三个数据包确认了从服务器到客户端的 SYN 数据包。而从客户端向服务器发送数据的第四个数据包再次确认了 SYN 数据包。

在携带有效载荷的数据包中发送 ACK 不会在线路上占用额外字节。ACK 位始终位于标头中,只需将其从 0 翻转为 1。被确认的序列号也始终存在,但其值只有在 ACK 位为 1 时才有意义。

通过对我的网络流量的快速检查,似乎除 SYN 和 RST 数据包之外的所有 TCP 数据包都设置了 ACK 位。

相关内容