TCP实验

发布时间 2024-01-03 11:22:28作者: 奶茶加盐

实验步骤

1、打开Wireshark软件捕捉数据包,在浏览器中访问网站,比如学校官网(IP地址为211.83.176.232)

2、在Wireshark中使用过滤器过滤出tcp包,再选择某一个客户端端口,过滤,只查看这个端口与服务器之间的通信。

3、分析数据包内容,以及通信过程。

理论

tcp报文首部格式

image-20231224133155058

接下来要着重分析的是序号,确认号,以及falg标志字段(URG、AKC、、、)

序号字段:占 4 字节。TCP 连接中传送的数据流中的每一个字节都编上一个序号。序号字段的值则指的是本报文段所发送的数据第一个字节的序号

确认号字段:占 4 字节,是期望收到对方的下一个报文段的数据的第一个字节的序号,也就是当前收到报文的最后一个字节的序号+1。 (也可以说是对刚才收到的报文进行确认,如果刚才收到的报文中的序号字段为seq=x数据部分有n个字节,那么对这个报文的进行确认的报文的确认号字段就要为ack=x+n+1

标志字段各部分含义:

  • 确认 ACK:只有当 ACK = 1 时确认号字段才有效。当 ACK = 0 时,确认号无效。
  • 推送 PSH (PuSH) :接收 TCP 收到 PSH = 1 的报文段,就尽快地交付接收应用进程,而不再等到整个缓存都填满了后再向上交付。
  • 复位 RST (ReSeT) :当 RST = 1 时,表明 TCP 连接中出现严重差错(如由于主机崩溃或其他原因),必须释放连接,然后再重新建立运输连接。
  • 同步 SYN :同步 SYN = 1 表示这是一个连接请求或连接接受报文。
  • 终止 FIN (FINish) :用来释放一个连接。FIN = 1 表明此报文段的发送端的数据已发送完毕,并要求释放运输连接。

tcp建立连接的三报文握手

image-20231224134358888

注意:

  • SYN是标志字段中的同步SYN,为1时表示这个报文是连接请求,或接受连接。
  • seq是首部中的序号字段,发送方为发送的每一个字节都编上一个序号,序号字段的值则指的是本报文段所发送的数据第一个字节的序号。由于tcp在进行建立连接或释放连接时,数据部分都为空seq是数据部分的第一个字节,也是整个报文的最后一个字节),所以如果接收方接收到一个序号为seq=x的报文,那么要对其进行确认的报文的确认号字段就应该为ack=x+1
  • 客户端与服务器所发送的seq之间是没有必然联系的,它们所发送的seq的值只取决于自己发送的字节数的多少。
  • 但发送方所发送的ack却与刚才收到的seq有关,关系为发送方要发送的ack=刚才收到的报文的seq+刚才收到的报文的数据部分的字节数+1

tcp释放连接的四报文握手

image-20231224140650038

当客户端请求释放连接,并收到服务端的同意后,客户端不能再发送数据,但仍然需要接受数据。服务端既可以发送数据,也可以接受数据(实际上由于客户端不在发送数据了,所以服务器端是收不到的)

实验过程

打开Wireshark捕捉数据包,再打开浏览器访问学校官网(211.83.176.232),官网界面加载出来后关闭浏览器,以免数据太多找不到TCP的FIN释放连接。

对捕获到的结果使用过滤器ip.addr==211.83.176.232 and tcp.port == 59845进行过滤,结果如下:

image-20231224142235549

再捕获结果中443是服务器端口,是固定的,59845是客户端的端口,是我从多个端口中选择的一个。为方便表示,下面使用45和43分别表示客户端和服务器。

建立连接

分析前几行的数据包,观察tcp建立连接的过程。

image-20231224143541998

与tcp连接建立的示意图相匹配

image-20231224143538075

45向43请求建立连接的数据包内容

image-20231224144900251

43同意45建立连接的请求的数据包的内容

image-20231224145654655

这里的相对序号可能说的是对于45与43之间通信的序号吧,计算机一旦联网肯定会同时产生很多的tcp数据,为了方便分析,所以这里可能就使用这样的相对序号。

传输数据

关于序号与确认号之间的关系,截取数据传输过程中的一对数据包进行分析

image-20231224151146062

43给45发送一个数据包(记为数据包A),seq=14819,len=1400,也就是说,数据部分是从14819到14819+1400-1=16218之间。所以这个报文的最后一个字节的编号为为16218,数据包A的ACK=1335,说明它希望下一个收到的数据包的seq=1335,也就是数据部分的第一个字节的编号为1335。

45个43发送一个数据包(记为数据包B),seq=1335,刚好就是数据包A所期望收到的。ACK=16219,说明它期望收到的下一个数据包的seq=16219,(也可以理解为是对数据包A的确认),因为数据包A的最后一个字节的编号是16218,如果43还要发送一个数据包,那么这个数据包的编号就应该从16219开始编号。

image-20231224153834738

上图中,43给45发送了很多数据,而45也给43发送数据进行了确认,但为什么43发送的数据的AKC都是1335呢?

因为45虽然给45发送了数据确认,但数据包中只有首部,数据部分为空,而seq的编号是对tcp的数据部分进行编号,数据部分的长度len一直为0,那么无论发送多少个数据包,编号都不会变,所以45的seq一直保持为1335,它既是当前包的数据部分的最后一个字节的编号,也是下一个包的数据部分的第一个字节的编号(seq)。43期望收到45的编号为1335的字节的数据,但由于45一直没有发送数据(数据部分为空),所以43的下一个包也是期望收到1335(ACK=1335)。

当45给43发送数据后,45的seq就变了,43的ACK也随之改变。从上图中的超时的数据包可以看出,45发送了769字节的数据,所以45发送的最后一个字节的编号由原来的1334变为了现在的2103,(1334+769或1335+769-1)。接下来,43期望收到的就是从2104开始的数据了(ACK=2104)。

释放连接

这里释放连接时倒是和示意图有些不同,可以是由于服务端没有数据需要继续传送了,所以就将第2步和第3步合并成了一步,服务器对释放连接的请求进行确认的同时也将自己的连接释放。

image-20231224160040240

image-20231224160214039

123