TCP —— 传输控制协议

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/ling_hun_pang_zi/article/details/82289609

TCP —— 传输控制协议

资料:《图解TCP/IP》

目录

使用TCP协议通信的双方必须先建立连接,然后才能开始数据的读写。双方都必须为该连接分配必要的内核资源,以管理连接的状态和连接上数据的传输。

TCP头部结构

这里写图片描述

16位源端口号和目的端口号:告知主机该报文是从哪儿来(源端口),要往哪去,传给上层的哪个应用程序的(目的端口)。进行TCP通信时,客户端通常使用系统自动选择的临时端口号,而服务器使用知名服务端口号。

32位序号:指的是一次TCP通信(从TCP连接建立到断开)过程中某一个传输方向上的字节流的每个字节的编号。

32位确认序号:用作对另一方发送来的TCP报文段的响应,其值是收到的TCP报文段的序号值加1。

4位首部长度:标识该TCP头部有多少个32bit字节。因为4位最大能表示15,所以TCP头部最长是60字节。

6位标志位

  • URG标志:表示紧急指针是否有效。
  • ACK标志:表示确认号是否有效。我们称携带ACK标志的TCP报文段为确认报文段。
  • PSH标志:提示接收端应用程序应该立即从TCP接收缓冲区中把数据读走。
  • RST标志:表示要求对方重新建立连接。我们称携带RST标志的TCP报文段为复位报文段。
  • SYN标志:表示请求建立一个连接。我们称携带SYN标志的TCP报文段为同步报文段。
  • FIN标志:表示通知对方本端要关闭连接了。我们称携带FIN标志的TCP报文段为结束报文段。

16位窗口大小: 是TCP流量控制的一个手段。能告知对方自己的TCP缓冲区还能容纳多少字节的数据,这样对方就可以控制发送数据的速度。

16位校验和:由发送端填充,接收端对TCP报文段执行CRC校验,以检验TCP报文段在传输过程中是否损坏。注意,这个校验不仅包括TCP头部,也包括数据部分。这也是TCP可靠传输的一个重要保障。

序列号与确认应答(ACK)机制

在TCP中,当发送端的数据到达接收主机时,接收端主机会返回一个已收到的消息通知,这个消息叫做确认应答。

数据包丢失的情况:

① 主机A给主机B发送消息,可能因为网络拥堵等原因,可能导致数据丢失,数据无法到达主机B。此时主机A在一个特定时间间隔内都未收到主机B发来的确认应答,将会对此数据进行重发。
这里写图片描述

② 对方已收到数据,只是在返回的确认应答在途中丢失。这种情况会导致发送端没有收到确认应答,而认为数据没有到达目的地,从而进行重新发送。
这里写图片描述

TCP将每个字节的数据都进行了编号,即为序列号。每一个ACK都带有对应的确认序号,意思是告诉发送者,我已经收到了哪些数据,下一次你从哪里开始发。
通过序列号和确认应答号,TCP就实现了可靠传输。

超时重传机制

重发超时是指在重发数据之前,等待确认应答到来的那个特定时间间隔,如果超过了这个时间仍未收到确认应答,发送端将进行数据重发。

那么超时的时间如何确定呢?

TCP要求不论在何种网络环境下都要提供高性能通信,并且无论网络拥堵情况发生何种变化,都必须保持这一特性。为此,TCP会动态计算这个最大超时时间。

在BSD的Unix以及Windows系统中,超时都以0.5秒为单位进行控制,因此重发超时都是0.5秒的整数倍。

数据被重发之后若还是收不到确认应答,则进行再次发送,此时,等待确认应答的时间将会以2倍、4倍的指数函数延长。

此外,数据也不会无限、反复地重发。达到一定重发次数之后,如果仍没有任何确认应答返回,就会判断为网络或对端主机发生了异常,强制关闭连接。

面向连接

TCP会在数据通信之前,通过TCP首部发送一个SYN包作为建立连接的请求,等待确认应答。如果对端发来确认应答,则认为可以进行数据通信。如果对端的确认应答未能到达,就不会进行数据通信。此外,在通信结束时会进行断开连接的处理(FIN包)。
这里写图片描述
详细参考TCP的三次握手、四次挥手。

滑动窗口

TCP对每一个发送的数据段都要给一个ACK确认应答,收到ACK后再发送下一个数据段。这样做的话会导致性能较差,尤其是往返的时间较长的时候。
这里写图片描述

为解决这个问题,TCP引入了窗口来控制提高速度。即使在往返时间较长的情况下,也能控制网络性能的下降。
确认应答不再是分段,而是以更大的单位进行确认。
这里写图片描述

窗口大小指的是无需等待确认应答而可以继续发送数据的最大值。上图的窗口大小为4000个字节。实现了对多个段同时进行应答的功能。

收到第一个ACK后,滑动窗口向后移动,逆序发送后面的数据,依次类推。
这里写图片描述

在这种情况下,如果发生丢包,应如何重传?

①数据包已到达,ACK丢了。
这里写图片描述

在这种情况下,数据已到达对端,是不需要再进行重发的。

② 数据包丢失
这里写图片描述

当某一报文段丢失后,发送端会一直收到确认号为1001的确认应答,就像是在提醒发送端“我想接收的是从1001开始的数据”。

如果发送端连续3次收到同一个确认应答,就会将其对应的数据进行重发。
这种机制比之前的超时管理更加高效,因此也被称作高速重发机制。

流量控制

接收端处理数据的速度是有限的,如果发送端发送的太快,导致接收缓冲区满了,这个时候如果发送端继续发送数据,就会造成丢包,继而引起丢包重传等一系列反应。

为了防止这种现象发生,TCP提供一种机制,让发送端根据接收端的实际接受能力控制发送的数据的多少,这就是流量控制。

在TCP首部中,专门有一个字段用来通知窗口大小,接收主机将自己接收的缓冲区大小放入这个字段中通知给发送端,这个字段的值越大,说明网络的吞吐量越高。

接收端的这个缓冲区一旦面临数据溢出时,窗口大小的值也会随之被设置为一个更小的值来通知给发送端,从而控制数据发送量。这就形成了一个完整的TCP流量控制。
这里写图片描述

当接收端的缓冲区满时,要停止接收数据,进行窗口更新通知,如果这个窗口更新的通知在途中丢失,可能会导致无法继续通信。

为避免这种情况发生,发送端主机会时不时的发送一个叫做窗口探测的数据段,此数据仅含一个字节以获取最新的窗口大小的信息。

拥塞控制

拥塞控制主要用来避免两种现象,包丢失和超时重传。

TCP有了滑动窗口后,就能够高效可靠的发送大量数据了,但是如果在刚开始通信的时候就发送大量数据,就可能引发其他的问题。

网络中有很多台计算机,如果当前网络状态已经比较拥堵了,贸然发送大量的数据,很有可能导致整个网络的瘫痪。

TCP为了防止这个问题出现,引入了慢启动机制,在通信一开始先发少量的数据探探路,摸清当前网络的拥堵情况后,再决定按照多大的速度传输数据。
这里写图片描述
首先,为了在发送端调节所要发送数据的量,定义了一个叫做“拥塞窗口”的概念。

于是在慢启动的时候,将这个拥塞窗口的大小设置为1,之后每收到一次ACK应答,拥塞窗口的值就加1。

每次发送数据包时,将拥塞窗口的大小与接收端主机通知的窗口大小做比较,取它们当中较小的那个值作为实际发送的窗口。

像上面这样,随着包的每次往返,拥塞窗口也会出现指数倍的增长,拥堵情况还是会导致网络拥塞的情况发生。为了防止这些,引入了慢启动阈值的概念。

当拥塞窗口超过这个阈值的时候,就不再按照指数方式增长,而是按照线性方式增长。
这里写图片描述

TCP通信开始时,慢启动阈值等于窗口的最大值。

在超时重发时,慢启动的阈值为当时拥塞窗口一半的大小。

延迟应答

接收数据的主机如果每次都立刻回复确认应答的话,可能会返回一个较小的窗口。那是因为刚接收完收据,缓冲区已满。

举个栗子:

我们假设接收缓冲区为1M,一次收到了500K的数据,如果立刻应答,返回的窗口大小就是500K。

但实际上可能处理端的速度非常快,10ms之内就把这500K的数据从缓冲区中取走了。

在这种情况下,接收端稍微等一会儿应答,这个时候返回的窗口大小就为1M了。

所以大可不必为每一个数据段都进行确认应答。在TCP文件传输中,绝大多数是每两个数据段返回一次确认应答。
这里写图片描述

捎带应答

捎带应答是指在延迟应答的基础上实现的,是指在TCP包中既发送数据又发送确认应答的一种机制。

在现实生活中,我们在接收到一个消息时,会对其进行回复。

比如A主机发送“How are you?”,

B主机会回复“Fine,Thank you”,这时ACK就可以退搭顺风车,和B主机回复的Fine,Thank you”一同回复给A主机。

这里写图片描述

猜你喜欢

转载自blog.csdn.net/ling_hun_pang_zi/article/details/82289609