咱们关注的就是序号和确认号html
这两者也是 TCP 实现可靠传输的方式。下图是一次随便抓包的截图(相对序列号)shell
在TCP传输中,每个字节都是有序号的,从0开始。经过序号的方式保存数据的顺序,接收端接受到以后进行从新排列成为须要的数据。网络
所以,我对于SEQ和ACK的了解就是:tcp
SEQ 表明:发送的这个包中第一个字节(若是有payload的话)的序号大数据
ACK 表明:已成功接受序列号到 ack-1 的数据,指望接收的下一个字节的序号为 ackcode
举例说明:htm
我已经发送了前100字节的数据,那么我下一个发送的包(若是发送窗口还有空间)的SEQ就是101,好比要发送10字节的数据,那么下一个包中的数据的字节编号就是 101 - 110. 以后若是继续发送的话,序号就是从111开始。blog
若是接收端接到了这个10字节的包的话,便会返回一个 ACK 为 111 的包,表示前面110个字节已经成功接收。ip
细心的同窗可能会发现,为何在创建链接的时候,发送的 SYN 包大小(payload)明明是0字节,可是接收端却返回 ACK = 1 ,还有断开链接的时候 FIN 包也被视为含有1字节的数据。get
缘由是 SYN 和 FIN 信号都是须要 acknowledgement 的,也就是你必须回复这个信号,若是它不占有一个字节的话,要如何判断你是回复这个信号仍是回复这个信号以前的包呢?
例如:若是 FIN 信号不占用一个字节,回复 FIN 的 ack 包就可能被误认为是回复以前的数据包被从新发送了一次,第二次挥手没法完成,链接也就没法正常关闭了。
ISN是不能hard code的,否则会出问题的——好比:若是链接建好后始终用1来作ISN,若是client发了30个segment过去,可是网络断了,因而 client重连,又用了1作ISN,可是以前链接的那些包到了,因而就被当成了新链接的包,此时,client的Sequence Number 多是3,而Server端认为client端的这个号是30了。全乱了。RFC793中说,ISN会和一个假的时钟绑在一块儿,这个时钟会在每4微秒对ISN作加一操做,直到超过2^32,又从0开始。这样,一个ISN的周期大约是4.55个小时。由于,咱们假设咱们的TCP Segment在网络上的存活时间不会超过Maximum Segment Lifetime(缩写为MSL – Wikipedia语条),因此,只要MSL的值小于4.55小时,那么,咱们就不会重用到ISN。
如图所示,在抓包的时候,常常会看到[TCP segment of a reassembled PDU ] 字样的包,这个表明数据在传输层被分包了。也就是表明包大小大于MTU,此处放一下MTU与MSS区别:
MTU(Maximum Transmission Unit)最大传输单元,在TCP/IP协议族中,指的是IP数据报能通过一个物理网络的最大报文长度,其中包括了IP首部(从20个字节到60个字节不等),通常以太网的MTU设为1500字节,加上以太帧首部的长度14字节,也就是一个以太帧不会超过1500+14 = 1514字节。
MSS(Maximum Segment Size,最大报文段大小,指的是TCP报文(一种IP协议的上层协议)的最大数据报长度,其中不包括TCP首部长度。MSS由TCP连接的过程当中由双方协商得出,其中SYN字段中的选项部分包括了这个信息。若是MSS+TCP首部+IP首部大于MTU,那么IP报文就会存在分片,若是小于,那么就能够不须要分片正常发送。
所以,出现这种现象的缘由就是你调用一次send的时候,send的数据比 MSS 还要打,所以就被协议栈进行了分包。
顺便说一下,IP数据包的分片是经过flag字段和offset字段共同完成的。
从图中能够看到,第6个和第5个包是同一个TCP报文被分红了两个包。若是咱们点开看的话,能够看到两个报文的ACK序号都同样,而且这些报文的Sequence Number都不同,而且后一个Sequence Number为前一个Sequence Number加上前一个报文大小再加上1 。这也是判断reassembled 的方式。
点开第6个包,能够看到它将5和6的数据整合起来了。