CCNA-Part5 - 传输层 ,TCP 为什么是三次握手? (2)

在 TCP Header 中有一个叫窗口大小的字段。当路由器发送或者接收数据时,会将数据先缓存起来,这个窗口就是对应的缓存区。由于造价的不同,不同的设备对应的缓冲区大小也不一样。考虑这样一种情况,客户端的窗口大小为 3 Byte,但服务端的窗口大小为 2 Byte。这就意味着,服务端只能先缓存 2 Byte 的数据。接着来看下,TCP 是如何进行流量控制的:

第一次,客户端会给服务端直接发送 3 Byte 的数据,注意是通过一个包里面包含 3 Byte 的数据。但由于服务端只有 2 Byte 的缓存空间,第三个 Byte 的内容会被丢掉。

接着服务端会回报,进行 ACK 确认,发送 ack=3,代表接受到了 seq=2 之前的数据。同时还会发送窗口大小 WS(2)告诉客户端自己只有 2 Byte 的缓存空间。

之后客户端只会发送缓存空间为 2 的数据包给服务端。

考虑一种特殊的情况:

在服务端收到 2 Byte 的数据时,此时 CPU 的处理变得低效,只从缓冲空间中取出了 1 个字节发送终端。

这时服务端再给客户端回包时,除了正常回复 ack=x+1 的确认,还会改变窗口大小为 1.,这就意味着告诉服务端,下次给我发包时

只能接受一个 Byte 的数据。

CCNA-Part5 - 传输层 ,TCP 为什么是三次握手?

实际抓包看一下,这里以访问百度为例子:

第一次握手:

CCNA-Part5 - 传输层 ,TCP 为什么是三次握手?

结合之前说的:

在 Flag 字段中,SYN 置1,表示这是一个请求连接的报文。

seq=0,注意这里的 0 只是抓包软件的相对值,真实值是下面的 ac f7 f8 8b.

源端口为:8548

目的端口为:443

再看第二次握手:

CCNA-Part5 - 传输层 ,TCP 为什么是三次握手?

同样:

服务端再 Flag 为 SYN 和 ACK 置位,表示该报具有确认和请求连接的功能。

ack = ac f7 f8 8c 正好是之前 seq 的大小 +1.

seq = 0,其实这里也是相对的位置,真实值为 fd 15 e1 c4,在 ack 的前四字节就是 syn.

最后第三次握手:

CCNA-Part5 - 传输层 ,TCP 为什么是三次握手?

表示客户端确认和服务建立连接,对应 Flag ACK 置位。

ack = fd 15 e1 c5, fd 15 e1 c4 + 1.

断开连接:

理解了 TCP 连接的过程,再看断开连接就很容易了。一样的,首先要明确,已经建立的连接是双向的连接。如果想要断开的话,自然双方都要发起一个请求。

而报文内部也大致相同,仅仅是把 Flag 字段中 SYN 换成 FIN 字段,表示想要断开连接。

同样,假如有客户端和服务端已经建立了连接。

客户端向服务端发送报文,其中 FIN=1,表示请求断开连接。(断开的是客户端到服务端的连接)

服务端收到后回包,ACK=FIN+1,表示收到客户端的情况,确认断开。

服务端再次发送请求,置位 FIN=1,表示要和服务端断开连接。(断开的是服务端到客户端的连接)

客户端收到后,ACK=FIN+1,表示确认断开和服务的连接。

这里一定会有疑问,为什么在三次握手中,可以在一个数据包中同时置位 SYN 和 ACK 表示确认和请求连接的过程,等到了断开连接时,就不能这样做呢,而是需要发送两次。

原因就在于,由于连接是双向的,第1,2步骤表示,客户端已经没有数据发送给服务端了。但这时,服务端可能还有数据正在发送给客户端,等待数据发送完成后。才能进行 3,4 步骤,然后断开服务端到客户端的连接。

UDP 报文段

学习了 TCP,再看 UDP 自然就很简单了。

先看 UDP 的特性:

工作在传输层

执行有限制的差错校验

提供尽力而为的传输

不可能的传输

开销低,传输的效率高

CCNA-Part5 - 传输层 ,TCP 为什么是三次握手?

可以看到,UDP 的 Header 中,仅有源端口,目的端口用于识别应用程序。

下面来比较一下 TCP 和 UDP:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zywdjg.html