详解TCP可靠传输、滑动窗口、流量控制、拥塞控制、三次握手四次挥手工作过程

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6


1、TCP协议概述

使用TCP和UDP的应用层协议

应用

应用层协议

传输层协议

名字转换

DNS(域名系统)

UDP

IP地址配置

DHCP(动态主机配置协议)

UDP

远程文件服务器

NFS(网络文件系统)

UDP

电子邮件

SMTP(简单邮件传输协议)

TCP

远程终端接入

TELNET(远程终端协议)

TCP

万维网

HTTP(超文本传输协议)

TCP

文件传送

FTP(文件传输协议)

TCP

套接字socket=ip:port
端口号:16位,因此一台主机最多有65535个端口号。

端口号分类:

服务端端口号:

  • 熟知端口号:0~1023
  • 登记端口号:1024~49151

客户端端口号(短暂端口号):49151~65535

常用的熟知端口号

应用程序

FTP

TELNET

SMTP

DNS

HTTP

HTTPS

熟知端口号

21

23

25

53

80

443

TCP:面向连接

UDP:面向报文

TCP主要特点:

  • 面向连接;
  • 每一条TCP连接只能有两个端点,即每条TCP连接是点对点(一对一)的;
  • 提供可靠交付的服务:无差错、不丢失、不重复、按序到达;
  • 全双工通信:TCP的两端都设有发送缓存和接收缓存,用来临时存放双向通信的数据;在发送时,应用程序在把数据传送给TCP的缓存后,就可以做自己的事,而TCP在合适的时候把数据发送出去;在接收时,TCP把收到的数据放入缓存中,上层的应用进程在合适的时候读取缓存中的数据;
  • 面向字节流:虽然应用程序和TCP交互的是一次一个数据块(大小不等),但TCP将数据块看成是一连串的字节流,因此,有可能发送方的应用程序发了10个数据块给TCP,但接收方的TCP只用了4个数据块就把接收到的数据交付给了应用程序,而双方的字节流其实是一模一样的;

TCP并不关心应用程序一次把多长的报文发送到TCP缓存中,而是根据对方给出的窗口值和当前网络拥塞的程度来决定一个报文段应包含多少个字节;而UDP发出的报文长度是由应用程序决定的;

如果应用程序传送到TCP的数据块太长,TCP就可以把它划分短一些再传送,如果太短,则TCP等累积到足够多的字节再传送。

下面介绍一下TCP的报文首部、可靠传输、滑动窗口、流量控制、拥塞控制、三次握手与四次挥手。

2、TCP报文首部格式

详解TCP可靠传输、滑动窗口、流量控制、拥塞控制、三次握手四次挥手工作过程_TCP

  • 序号

TCP是面向字节流的,在一个TCP连接中传输的字节流中的每一个字节都按顺序编号。首部中的序号字段值是本报文段所发送数据的第一个字节的序号。

例如,本报文段首部的序号字段值为301,数据部分携带100个字节,这就说明,本报文段的数据的序号是从301到400,下一个报文段首部的序号字段值为401。

序号一共占32位,可对4GB的数据进行编号,如果在一个TCP连接中数据超过了4GB怎么办?序号又会从0开始,而旧的0号数据早已到达终点,因此不必担心序号重复的问题。

  • 确认号

期望收到对方下一个报文段的第一个数据字节的序号.若确认好为N,则表示N-1及N-1往前的数据已确认接收。

  • 数据偏移

数据偏移实际表示TCP报文首部长度。数据偏移占4位在,最大能表示15。

由于每行占4个字节,因此首部最大为15*4=60个字节,而有20字节的固定首部,因此选项部分最大为40字节。

6个控制位:

  • 紧急URG:当URG为1时,则表示此报文段有紧急数据,应尽快传送(优先级更高),于是发送方的TCP会将紧急数据插入到数据的最前面。配合紧急指针使用;
  • 确认ACK:当ACK=1时,确认号有效,ACK=0时,确认号无效。TCP规定当连接建立后,所有报文段的ACK都置为1;
  • 推送PSH
  • 复位RST
  • 同步SYN:在连接建立时用来同步序号。当SYN=1且ACK=0时表示这是一个连接请求报文段,对方若同意连接,则响应报文段SYN=1且ACK=1,因此SYN=1表示这是一个连接请求或响应报文;
  • 终止FIN:当FIN=1时,表示要求释放连接;
  • 紧急指针

当控制位URG=1时有效。紧急指针存储的是紧急数据与普通数据的分界线。

  • 窗口

接收方的窗口,比如窗口值为1000,意味着告诉发送方:我目前最大能接收1000个字节,你发送数据时不要超过这么多。窗口值是动态变化的

  • 校验和

选项:

最初只规定了一种选项:最大报文长度MSS(数据部分)

随着互联网发展,又新增了几种选项:

  • 窗口扩大选项:窗口字段占16位,最大为64KB,窗口扩大选项用来解决在带宽和时延大的网络中窗口值不够大的问题;
  • 时间戳:用来计算往返时间RTT和解决序号重复问题(越高速的网络中序号重复可能性越大);
  • 选择确认SACK;

3、可靠传输、滑动窗口与流量控制

TCP下面的网络层提供的是不可靠的传输。

理想的传输条件的特点:

  • 传输信道不产生差错;
  • 不管发送方以多快的速度发送数据,接收方总是来得及处理;

当然,实际的网络不满足这两个条件,因此需要一些手段:

  • 当出现差错时,让发送方重传出现差错的数据;
  • 当接收方来不及处理数据时,及时告知发送方降低发送速度;

停止等待协议(ARQ):每发送一条数据必须收到对方的确认,否则就超时重传。如下图所示。

详解TCP可靠传输、滑动窗口、流量控制、拥塞控制、三次握手四次挥手工作过程_TCP_02

连续ARQ协议(滑动窗口):ARQ效率太慢,因此连续ARQ协议使用累积确认的方式。如下图所示。

  • 假设窗口大小是5,那么可以连续发送5个数据,接收方只对最后一个数据确认即可,收到确认之后,窗口向右移动一步。
  • 如果中间的第3个数据丢失,接收方只能确认2这条数据,即1 2数据是没有问题的,而发送方认为3 4 5都有问题,需要重传,然而4 5是没有问题的,这也是连续ARQ协议的缺点。

详解TCP可靠传输、滑动窗口、流量控制、拥塞控制、三次握手四次挥手工作过程_滑动窗口_03

以字节为单位的滑动窗口(如下图所示):

  • TCP连接的两端,每一方都有自己的发送窗口和接收窗口;
  • 通常接收方的报文段首部的窗口字段会告诉接收方我最多能接收多少字节,因此发送窗口<=接收窗口。另外,发送窗口的大小还会受到网络拥塞的影响;
  • 由于窗口字段值是动态变化的,因此滑动窗口的大小是可伸缩的;
  • 滑动窗口越大,传输效率越高,且采用累积确认的方式。如果部分数据接收方没有确认,则发送方进行超时重传;

详解TCP可靠传输、滑动窗口、流量控制、拥塞控制、三次握手四次挥手工作过程_拥塞控制_04

流量控制

  • 利用滑动窗口机制实现在TCP连接上对发送方进行流量控制。

4、TCP拥塞控制

计算机网络中的链路容量(即带宽)、交换结点中的缓存和处理机等,都是网络的资源,当网络资源负载太大,网络性能就会变差,这种情况就叫做拥塞。

详解TCP可靠传输、滑动窗口、流量控制、拥塞控制、三次握手四次挥手工作过程_TCP_05

TCP拥塞控制算法:

  • 慢开始阶段:不能一开始发送大量字节到网络,而是慢开始,试探性地,指数增长,超过慢开始门限时改为拥塞避免算法;
  • 拥塞避免阶段:线性增长,发生超时改为慢开始算法,且调整慢开始门限=超时时的拥塞窗口值/2;
  • 快重传:发送方只要一连收到3个重复确认(往往不是网络拥塞导致的),立即进行快重传而不是超时重传,这样发送方就不会误以为网络拥塞;快重传之后采用快恢复算法;
  • 快恢复:调整门限值=拥塞窗口/2,且设置拥塞窗口值=门限值,紧接着执行拥塞避免算法(而不是调整窗口值=1,接着执行慢开始算法);

快重传的理论依据:个别报文段会在网络中丢失,但并不是网络拥塞导致的,如果不采取措施,发送方就会将此次超时认为是网络拥塞,从而错误地开启了慢开始算法,降低了传输效率。

解决方法:让接收方收到数据要立即发送确认,而不是等到发数据时才进行捎带确认;即使收到了失序的数据也要对上一次数据进行重复确认(如果不用快重传算法就可以什么都不做从而让发送方超时重传);紧接着发送方再发送两次数据,接收方再发送两次旧数据的重复确认,这样一共是一次有效确认和三次重复确认(上面只是讲述了重复确认的几种情况,实际发生可能是上面几种情况的其它组合),接收方接连收到三次重复确认,就知道M3没有收到,因此进行快重传(立即重传而不是超时重传)。紧接着执行快恢复。

发送方维持一个拥塞窗口,拥塞窗口大小取决于网络拥塞程度,且动态变化。让发送方的发送窗口=拥塞窗口。

拥塞窗口的原则:

  • 只要网络没有出现拥塞,则拥塞窗口可以再增大一些;
  • 如果网络出现拥塞(判断依据是出现了超时重传),则减小拥塞窗口,缓解网络中的拥塞;

详解TCP可靠传输、滑动窗口、流量控制、拥塞控制、三次握手四次挥手工作过程_UDP_06

这个图没有考虑接收方窗口大小(要考虑接收方缓存剩余容量),实际上发送窗口=min(接收方窗口大小,拥塞窗口大小)

TCP拥塞控制流程图:

详解TCP可靠传输、滑动窗口、流量控制、拥塞控制、三次握手四次挥手工作过程_计算机网络_07

 

5、三次握手建立连接

详解TCP可靠传输、滑动窗口、流量控制、拥塞控制、三次握手四次挥手工作过程_UDP_08

为什么是三次握手而不是两次或四次?

三次就足够了,四次就没必要了。

为什么不是两次?

因为TCP是全双工通信,除了要让A收到B的确认号,同时还要让B收到A的确认号,因此需要第三次握手。

还有一个原因是,防止已失效的连接请求报文突然又传送到了B,产生错误。

啥叫已失效的连接请求报文呢?

考虑到这样一种情况,A发送了连接请求报文,但由于网络不好没有到达B,A又重新发了一份连接请求报文到B,此时B收到了并成功建立了连接,如果第一份报文确确实实丢失了,那整个过程不会有错误。

如果第一份报文没有丢失,而是花了比较长的时间到达了B,然后B同意连接并向A发出连接响应报文,这已经进行了两次握手了,假设只有两次握手,那么已失效的连接请求报文都会导致A与B建立连接,如果是三次握手就能解决这个问题,因为即使A收到了B的连接响应报文,但A并没有发起连接啊,因此A不会理睬B的连接响应报文,也就不会进行第三次握手了。

6、四次挥手释放连接

详解TCP可靠传输、滑动窗口、流量控制、拥塞控制、三次握手四次挥手工作过程_TCP_09

为什么需要四次挥手?

  • 关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉Client端,"你发的FIN报文我收到了"。只有等到我Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四步握手。

如果已经建立了连接,但是客户端突然出现故障了怎么办?

  • TCP还设有一个保活计时器,显然,客户端如果出现故障,服务器不能一直等下去,白白浪费资源。服务器每收到一次客户端的请求后都会重新复位这个计时器,时间通常是设置为2小时,若两小时还没有收到客户端的任何数据,服务器就会发送一个探测报文段,以后每隔75秒钟发送一次。若一连发送10个探测报文仍然没反应,服务器就认为客户端出了故障,接着就关闭连接。

为什么TIME_WAIT状态需要经过2MSL(最大报文段生存时间)才能返回到CLOSE状态?

  • 虽然按道理,四个报文都发送完毕,我们可以直接进入CLOSE状态了,但是我们必须假设网络是不可靠的,有可以最后一个ACK丢失。所以TIME_WAIT状态就是用来重发可能丢失的ACK报文。在Client发送出最后的ACK回复,但该ACK可能丢失。Server如果没有收到ACK,将不断重复发送FIN片段。所以Client不能立即关闭,它必须确认Server接收到了该ACK。Client会在发送出ACK之后进入到TIME_WAIT状态。Client会设置一个计时器,等待2MSL的时间。如果在该时间内再次收到FIN,那么Client会重发ACK并再次等待2MSL。所谓的2MSL是两倍的MSL(Maximum Segment Lifetime)。MSL指一个片段在网络中最大的存活时间,2MSL就是一个发送和一个回复所需的最大时间。如果直到2MSL,Client都没有再次收到FIN,那么Client推断ACK已经被成功接收,则结束TCP连接。
阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6