计算机网络之TCP数据格式(二)

4 篇文章 0 订阅
4 篇文章 0 订阅

数据格式

在这里插入图片描述

序列号

在这里插入图片描述

确认应答号

在这里插入图片描述

数据偏移

即TCP首部的长度,首部长度=值*4
如果该字段的值为5,那说明从TCP包的最一开始到20字节为止都是TCP首部 ,余下的部分为TCP数据。

保留

一般为0,不为0也不丢弃数据。

控制位

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

窗口大小

在这里插入图片描述

校验和

见文末的Wireshark实例分析。

紧急指针

eg6IGK5Yiw5Y-R5Y2a5a6i55qE6I-c6bif,size_16,color_FFFFFF,t_70,g_se,x_16)

选项

在这里插入图片描述
类型2——MSS表示最大段长度

类型3——WS表示窗口比例,窗口大小只有2字节,最大只有64KB,对于现在的技术来说太小了。
所以实际窗口大小= 窗口大小 * 2^WS
例如窗口大小为8212 WS为8
那么实际窗口大小= 8212 * 256 = 2102272

类型4——SACK_PERM在SYN包中告诉对端自己支持SACK

类型5——SACK表示选择性重发,避免无用重发,提高网络吞吐量

类型8——时间戳在高速通信中,可以防止序列号回绕。两端必须都分别在SYN包和SYN|ACK包中开启时间戳选项,时间戳功能才能生效

Wireshark实例分析

通信过程示意

连接(三次握手)—> 通信 —> 断开(四次挥手)
在这里插入图片描述
客户端192.168.1.164:59160向服务端192.168.1.193:8888发起连接并发送字符串1234,由于长时间未通信,服务端进行主动断开。
在这里插入图片描述

连接

SYN

以SYN为例进行协议分析(蓝色部分为TCP协议部分)
在这里插入图片描述
源端口:e718->59160

目标端口:22b8->8888

序列号Seq:df15f6db->3742758619,发起连接时生成的随机值,Wireshark为了让我们方便分析,会从0开始,即采用一个相对值。

确认应答号Ack:00000000,除了第一包的SYN包不需要ACK标志,其余所有数据都必须携带ACK标志。ACK为下次对端应该发送的序列号,即ACK=上一次发送的Seq+Len

数据偏移(首部长):a->10,由于SYN包是不可以携带数据的,所以这整个包的长度就是10*4 = 40

保留:0

控制位:02->0000 0010 即 SYN包

窗口大小:faf0->64240

检验和:5b54,首先得知道校验和的概念,可参考我的上一篇文章《计算机网络之UDP数据格式(一)》
校验和概念可知伪首部为(UDP的协议号为17,TCP的协议号为6)

C0A801A4 C0A801C1 00 06 0028

校验和为伪首部首部(校验位补0)、数据(长度不为偶数补0)每16位一组进行二进制反码求和,再将求和结果求反码
附上Python计算校验和代码

pseudo_header =[0xC0A8, 0x01A4, 0xC0A8, 0x01C1, 0x0006, 0x0028]
tcp_data = [0xe718, 0x22b8, 0xdf15, 0xf6db, 0x0000, 0x0000, 0xa002, 0xfaf0,
0x5b54, 0x0000, 0x0204, 0x0402, 0x080a, 0x7eec, 0x0e56, 0x0000, 0x0000, 0x0103, 0x0307]

def checksum(data):
	s = 0
	for i in data:
		s += i
		s = (s & 0xffff) + (s >> 16) # 取前16位,然后将17位(进位的值加到第一位上)
	return (~s & 0xffff)

print(hex(checksum(pseudo_header+tcp_data)))

紧急指针:0000

选项——MSS:0204 05b4,即MSS为1460(0x05b4)

选项——SACK_PERM:0402,表示支持SACK

选项——时间戳:080a 7eec0e56 00000000,即TSval=2129399382,TSecr=0

选项——填充:01

选项——WS:0303 07,即实际窗口大小=64240 * 2^7

SYN|ACK

在这里插入图片描述
这里的Seq为0也是相对的,实际值为1675384059

看到这里或许会有疑问,为什么SYN包没有数据,这里的Ack会为1呢?因为SYN包和FIN包虽然不携带数据,但是Ack还是会加1。

这里也是有SACK_PERM,说明双方都支持SACK。

这里没有时间戳选项,两端必须都分别在SYN包和SYN|ACK包中开启时间戳选项,时间戳功能才能生效。

ACK

在这里插入图片描述
这里的Seq为1,是因为上一包的Ack为1。

这里的Ack为1,是因为上一包数据有SYN标志,虽然Len=0,但是依然会算一个长度。


通信

PSH|ACK

在这里插入图片描述
发送1234
seq = 1 ack = 1
PSH表示发送的数据不进行缓存,立即传给上层应用

ACK

在这里插入图片描述
seq = 1 ack = 5
收到了4个字节数据,这里的ack就变成5了


断开

FIN|ACK

在这里插入图片描述
seq = 1 ack = 5

ACK

在这里插入图片描述
seq = 5 ack = 2

虽然上一包数据的Len为0,但是上一包数据有FIN标志,所以依然会算一个长度。


RST|ACK

在断开的过程中,收到了FIN包回复ACK后,可以不用立即发送FIN包,可以等数据处理完之后再发送FIN包。
这里是因为超时未收到对端的FIN包,所以发送RST包进行强行断开。

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值