计算机网络入门(三)——快速理解TCP协议

TCP 协议的作用

互联网由一整套协议构成。TCP 只是其中的一层,有着自己的分工。
TCP 是以太网协议和 IP 协议的上层协议,也是应用层协议的下层协议:
在这里插入图片描述
最底层的以太网协议(Ethernet)规定了电子信号如何组成数据包(packet),解决了子网内部的点对点通信。
但是,以太网协议不能解决多个局域网如何互通,这由 IP 协议解决。 IP 协议可以连接多个局域网。

IP 协议定义了一套自己的地址规则,称为 IP 地址。它实现了路由功能,允许某个局域网的 A 主机,向另一个局域网的 B 主机发送消息。
路由器就是基于 IP 协议。局域网之间要靠路由器连接。

IP 协议只是一个地址协议,并不保证数据包的完整。如果路由器丢包(比如缓存满了,新进来的数据包就会丢失),就需要发现丢了哪一个包,以及如何重新发送这个包。这就要依靠 TCP 协议。

简单说,TCP 协议的作用是,保证数据通信的完整性和可靠性,防止丢包。

TCP 数据包的大小

以太网数据包(packet)的大小是固定的,最初是1518字节,后来增加到1522字节。其中, 1500 字节是负载(payload),22字节是头信息(head)IP 数据包在以太网数据包的负载里面,它也有自己的头信息,最少需要20字节,所以 IP 数据包的负载最多为1480字节。
在这里插入图片描述

TCP 数据包在 IP 数据包的负载里面。它的头信息最少也需要20字节,因此 TCP 数据包的最大负载是 1480 - 20 = 1460 字节。由于 IPTCP 协议往往有额外的头信息,所以 TCP 负载实际为1400字节左右。因此,一条1500字节的信息需要两个 TCP 数据包。

TCP 数据包的编号(SEQ)

一个包1400字节,那么一次性发送大量数据,就必须分成多个包。比如,一个 10MB 的文件,需要发送7100多个包。发送的时候,TCP 协议为每个包编号(sequence number,简称 SEQ),以便接收的一方按照顺序还原。万一发生丢包,也可以知道丢失的是哪一个包。

第一个包的编号是一个随机数。为了便于理解,这里就把它称为1号包。假定这个包的负载长度是100字节,那么可以推算出下一个包的编号应该是101。这就是说,每个数据包都可以得到两个编号:自身的编号,以及下一个包的编号。接收方由此知道,应该按照什么顺序将它们还原成原始文件。

在这里插入图片描述
▲ 当前包的编号是45943,下一个数据包的编号是46183,由此可知,这个包的负载是240字节

TCP 数据包的组装

收到 TCP 多个数据包以后,组装还原是操作系统完成的。应用程序不会直接处理 TCP 数据包。应用程序需要的数据放在 TCP 数据包里面,有自己的格式(比如 HTTP 协议)。

TCP 并没有提供任何机制,表示原始文件的大小,这由应用层的协议来规定。 比如,HTTP 协议就有一个头信息Content-Length,表示信息体的大小。 对于操作系统来说,就是持续地接收 TCP 数据包,将它们按照顺序组装好,一个包都不少

操作系统不会去处理 TCP 数据包里面的数据。一旦组装好 TCP 数据包,就把它们转交给应用程序。TCP 数据包里面有一个端口(port)参数,就是用来指定转交给监听该端口的应用程序。

应用程序收到组装好的原始数据,以浏览器为例,就会根据 HTTP 协议的 Content-Length 字段正确读出一段段的数据。这也意味着,一次 TCP 通信可以包括多个 HTTP 通信。

慢启动机制和 ACK

服务器发送数据包,当然越快越好,最好一次性全发出去。但是,发得太快,就有可能丢包。带宽小、路由器过热、缓存溢出等许多因素都会导致丢包。线路不好的话,发得越快,丢得越多。

最理想的状态是,在线路允许的情况下,达到最高速率。但是我们怎么知道,对方线路的理想速率是多少呢?答案就是慢慢试。

TCP 协议为了做到效率与可靠性的统一,设计了一个慢启动(slow start)机制。开始的时候,发送得较慢,然后根据丢包的情况,调整速率:如果不丢包,就加快发送速度;如果丢包,就降低发送速度。

Linux 内核里面设定了(常量TCP_INIT_CWND),刚开始通信的时候,发送方一次性发送10个数据包,即"发送窗口"的大小为10。然后停下来,等待接收方的确认,再继续发送。默认情况下,接收方每收到两个 TCP 数据包,就要发送一个确认消息。"确认"的英语是 acknowledgement,所以这个确认消息就简称 ACK

ACK 携带两个信息:

  • 期待要收到下一个数据包的编号;
  • 接收方的接收窗口的剩余容量。

注意:由于 TCP 通信是双向的,所以双方都需要发送 ACK。两方的窗口大小,很可能是不一样的。而且 ACK
只是很简单的几个字段,通常与数据合并在一个数据包里面发送。

假设左边是客户端A,右边是服务端B,通信过程:
在这里插入图片描述

  • 首先A主动与B通信,发了一个数据包(编号=1,期待B返回的数据包的编号=1,当前数据包长度=100)
  • B接受到了数据包后,与A进行一次通信,返回一个数据包,因为A期待的数据包的编号是1,所以seq=1;然后B期望下一次A返回的数据包的编号是Ack=1+100;当前数据包长度=200;
  • A接收到B返回的数据包后,与B进行一次通信,并发出一个数据包:
    seq=101 因为上一次A发送的数据包长度是100,编号是1,所以100+1,也就是B发来的Ack
    Ack=200+1;length=当前数据包的长度
  • 接下来都一样的分析就行

TCP 流量控制及拥塞控制的机制

流量控制:
TCP使用窗口机制来实现流量控制的。原理是:在通信过程中,接收方根据自己接收缓存的大小,动态调整发送方的发送窗口大小,即TCP报文段首部中的“窗口”字段rwnd,来限制发送方向网络注入报文的速率。同时,发送方根据其对当前网络拥塞程序的估计确定一个拥塞窗口cwnd最终A发送的窗口的实际大小是min(rwnd,cwnd)值

拥塞控制:
流量控制是端到端的交互,如果只是局域网内的两台设备交互,我想通过滑动窗口大概能控制得不差,但是实际网络的情况非常复杂,发送方和接收方之间还有路由器和交换机,网络传输线路又复杂,这个时候就需要拥塞控制。
拥塞控制主要有四个算法:慢启动、拥塞避免、快速重传和快速恢复。

https://www.cnblogs.com/iou123lg/p/9017044.html

数据包的遗失处理

TCP 协议可以保证数据通信的完整性,这是怎么做到的?
通过累计确认及超时重传机制实现数据正确性。
每一个数据包都带有下一个数据包的编号。如果下一个数据包没有收到,那么 ACK 的编号就不会发生变化。

举例来说:
在这里插入图片描述
如果一直没有发送101编号的包,反而跳过了该包,发了后面的包过来,那么服务端B,发送的包,ACK 里面的编号不会变化,总是显示101号包。如果发送方发现收到三个连续的重复 ACK,或者超时了还没有收到任何 ACK,就会确认丢包,即101号包遗失了,从而再次发送这个包。通过这种机制,TCP 保证了不会有数据包丢失。

总结

  • TCP 协议的作用:保证数据通信的完整性和可靠性,防止丢包
  • TCP 数据包的大小:head(20)+负载(1460)=1480 ;由于 IPTCP 协议往往有额外的头信息,所以 TCP 负载实际为1400字节左右
  • TCP 数据包的编号(SEQ):第一个包的编号是一个随机数。为了便于理解,这里就把它称为1号包。假定这个包的负载长度是100字节,那么可以推算出下一个包的编号应该是101。这就是说,每个数据包都可以得到两个编号:自身的编号,以及下一个包的编号。有了编号,发生了丢包,就可以知道丢的是哪个包。
  • TCP 数据包的组装:收到 TCP 多个数据包以后,组装还原是操作系统完成。一旦组装好 TCP 数据包,就把它们转交给应用程序。TCP 数据包里面有一个端口(port)参数,就是用来指定转交给监听该端口的应用程序。应用程序需要的数据放在 TCP 数据包里面,有自己的格式(比如 HTTP 协议)。原始文件的大小,这由应用层的协议来规定(如:HTTP协议就有一个头信息Content-Length)。应用程序收到组装好的原始数据,以浏览器为例,就会根据 HTTP 协议的 Content-Length 字段正确读出一段段的数据。
  • 慢启动和ACK
    • 慢启动(slow start)机制:开始的时候,发送得较慢,然后根据丢包的情况,调整速率:如果不丢包,就加快发送速度;如果丢包,就降低发送速度。
    • 发送方每发送一次数据包,就要等待接收方的确认,接受方收到数据包,会发送一个确认消息ACK。
      • ACK 携带两个信息:期待要收到下一个数据包的编号;接收方的接收窗口的剩余容量。
      • 通信过程:…
  • 数据包的遗失处理:每一个数据包都带有下一个数据包的编号。如果下一个数据包没有收到,那么接受法发送的ACK 的编号就不会发生变化。如果发送方发现收到三个连续的重复 ACK,或者超时了还没有收到任何 ACK,就会确认丢包,即xxx号包遗失了,从而再次发送这个包。通过这种机制,TCP 保证了不会有数据包丢失。

面试题

TCP 和 UDP 的区别?

  • TCP 是面向连接的,UDP 是面向无连接的;
  • UDP程序结构较简单
  • TCP 是面向字节流的,UDP 是基于数据报的
  • TCP 保证数据正确性,UDP 可能丢包;
  • TCP 保证数据顺序,UDP 不保证

什么是面向连接,什么是面向无连接?
在互通之前,面向连接的协议会先建立连接,如 TCP 有三次握手,而 UDP 不会

TCP 为什么是可靠连接?

  • TCP 报文头里面的序号能使 TCP 的数据按序到达
  • 报文头里面的确认序号能保证不丢包,累计确认及超时重传机制
  • TCP 拥有流量控制及拥塞控制的机制

猜你喜欢

转载自blog.csdn.net/weixin_42412601/article/details/107182244
今日推荐