TCP原理#

字段说明#

序号(SEQ)#

序号类似于自增ID,用于标识当前数据包在所有数据包中的位置,它的自增规则如下:

  • 发送一个序号字段不为空的数据包时,该数据包本身占一个序号,故响应包的确认号 = 发送方序号+data_length+1
  • 发送一个序号字段为空的数据包时(如纯ACK响应),该数据包本身不占序号,故响应包的确认号 = 发送方序号+data_length

确认号(ACK)#

用于接收方通知发送方,前面的包已经收到无误,且下次希望收到序号为几的包。

首部长度字段#

表示TCP头部一共占几个32bit,也就是说,TCP头部的最大长度为 = (2^4-1) * (32/8) = 15 * 4 = 60字节。

窗口#

用于接收方通知发送方,自己的接受缓存区剩余字节数,最大为2^16-1=65535,当需要更大值时,通常加入窗口缩放因子字段(window scale),例如窗口字段为2048,缩放因子为8,则实际窗口大小为:2048 « 8。

标志位#

URG 紧急指针(u rgent pointer)有效 。 ACK 确认序号有效。 PSH 接收方应该尽快将这个报文段交给应用层。 RST 重建连接。 SYN 同步序号用来发起一个连接。 FIN 发端完成发送任务。

连接过程#

A>B 随机一个序号A_SEQ:100,(意义:告诉B,A的初始序号) 确认号:空 在控制区设置SYN:1 在选项区添加MSS:1460,(意义:告诉B,A能接受的最大数据区大小,通常为1460:MAC包1514-MAC头14-IP头20-TCP头20)

A<B 随机一个序号B_SEQ:200,(意义:告诉A,B的初始序号) 确认号:101(A_SEQ+data_length+1),(意义:告诉A,B想要序号为几的包,上一条SYN本身占一个序号) 在控制区设置SYN:1 在控制区设置ACK:1 在选项区添加MSS:1460,(意义:告诉A,B能接受的最大数据区大小,通常为1460:MAC包1514-MAC头14-IP头20-TCP头20)

A>B(纯ACK响应) 序号A_SEQ:空 确认号:201(B_SEQ+data_length+1),(意义:告诉B,A想要序号为几的包,上一条SYN本身占一个序号) 在控制区设置ACK:1 在选项区添加最大序列大小字段,通常为1460(MAC包1514-IP头20-TCP头20)MSS:1460

发送数据过程#

A>B(发送三个字节abc) 序号A_SEQ:101,(意义:告诉B,这是序号为几的包) 确认号:201(B_SEQ+data_length+1),(意义:告诉B,A想要序号为几的包) 在控制区设置PUS:1 在控制区设置ACK:1 选项区:空

A<B(纯ACK响应) 序号B_SEQ:空 确认号:101+3+1(A_SEQ+data_length+1),(意义:B想要序号为几的包) 在控制区设置ACK:1 选项区:空

断开过程#

A>B 序号A_SEQ:105,(意义:告诉B,这是序号为几的包) 确认号:201(B_SEQ+data_length+1),(意义:告诉B,A想要序号为几的包) 在控制区设置FIN:1 在控制区设置ACK:1 选项区:空

A<B(纯ACK响应) 序号B_SEQ:空 确认号:106(A_SEQ+data_length+1),(意义:告诉A下次从第几字节开始) 在控制区设置ACK:1 选项区:空

A<B 序号B_SEQ:201,(意义:告诉A,这是序号为几的包) 确认号:106(A_SEQ+data_length+1),(意义:告诉A下次从第几字节开始) 在控制区设置FIN:1 在控制区设置ACK:1 选项区:空

A>B(纯ACK响应) 序号A_SEQ:空 确认号:202(B_SEQ+data_length+1),(意义:告诉B,A想要序号为几的包,上一条FIN本身占一个序号) 在控制区设置ACK:1 选项区:空

TCP状态变化#

参考#

  • TCP/IP详解-卷1
  • TCP/IP详解-卷3



本站所有作品均采用知识共享署名-非商业性使用-禁止演绎 3.0 中国大陆许可协议进行许可。