网络层负责把分组发送到目的主机,但是真正通信的并不是主机而是主机中的进程。传输层提供了进程间的逻辑通信,传输层向高层用户屏蔽了下面网络层的核心细节,使应用程序看起来像是在两个传输层实体之间有一条端到端的逻辑通信信道。
一.传输层中的两种协议UDP / TCP
UDP 的特点:
用户数据报协议 UDP(User Datagram Protocol):是无连接的,不具有可靠性的数据报协议,细微的处理它会交给上层的应用去完成.UDP尽最大可能交付,没有拥塞控制,面向报文(对于应用程序传下来的报文不合并也不拆分,只是添加 UDP 首部),支持一对一、一对多、多对一和多对多的交互通信,类似于发短信.UDP情况下,虽然可以确保发送消息的大小,却不能保证消息一定会到达。因此,应用有时会根据自己的需要进行重发处理.
UDP不提供复杂控制机制,利用IP提供面向无连接的通信服务。且它是将应用程序发来的数据在收到的那一刻,立即按照原样发送到网络上的一种机制。
UDP面向无连接,可以随时发送数据。它常用于几个方面:
包总量较少的通信(DNS、SNMP等)
视频、音频等多媒体通信(即时通信)
限定于LAN等特定网络中的应用通信TCP的特点:
传输控制协议 TCP(Transmission Control Protocol):是面向连接的、可靠的流协议。流就是指不间断的数据结构,你可以把它想象成排水管道中的水流。TCP提供可靠交付,实行“顺序控制”或“重发控制”机制,具有流量控制,拥塞控制,提供全双工通信,面向字节流(把应用层传下来的报文看成字节流,把字节流组织成大小不等的数据块),具有提高网络利用率等众多功能,每一条 TCP 连接只能是点对点的(一对一),类似于打电话.
TCP充分实现了数据传输时各种控制功能,根据TCP这些机制,在IP这种无连接的网络上也能够实现高可靠性的通信。
TCP通过校验和、序列号、确认应答、重发机制、连接管理以及窗口控制等机制实现可靠性传输。
UDP / TCP 的选择与区分:
TCP用于在传输层有必要实现可靠传输的情况。由于它是面向有连接并具备顺序控制、重发控制等机制的,所以他可以为应用提供可靠传输。UDP主要用于那些对高速传输和实时性有较高要求的通信或广播通信。多播和广播通信中也使用UDP而不是TCP。RIP、DHCP等基于广播的协议也要依赖于UDP。
TCP是紧小细微型的工作方式,提供可靠的通信传输;而UDP是粗狂蛮干型的工作方式,常被用于让广播和细节控制交给应用的通信传输.
TCP可靠性高,速度慢,可被利用的漏洞多;UDP速度快,可靠性低,可被利用的漏洞少,相对较安全.
因为UDP协议的控制选项较少,在数据传输过程中延迟小、数据传输效率高,实时性好,适合对可靠性要求不高的应用程序,或者可以保障可靠性的应用程序,如DNS、TFTP、SNMP等。 在生活中音频、视频和普通数据都可以采用UDP协议来进行数据传输.
当对网络通讯质量有要求,整个数据需要准确无误的传递给对方时,比如HTTP、HTTPS、FTP等传输文件的协议,POP、SMTP等邮件传输的协议需采用TCP协议。
套接字(Socket)
使用TCP或UDP通信时,会广泛使用到套接字(socket)的API。套接字原本是由BSD UNIX开发的,但是后被移植到Windows以及嵌入式操作系统中。
应用程序利用套接字,可以设置对端的IP地址、端口号,并实现数据的发送和接收。
二.传输层中的端口号
IP首部有一个协议字段,用来标识网络层(IP)的上一层所采用的是哪一种传输层协议。根据这个字段的协议号,就可以识别IP传输的数据部分究竟是TCP的内容还是UDP的内容。
同样,传输层的TCP和UDP,为了识别自己所传输的数据部分究竟应该发给哪个应用,也设定了这样一个编号。在TCP/IP通信中需要指定“应用程序”。而传输层必须指出这个具体的程序,为了实现这一功能,使用端口号这样一种识别码。根据端口号可以识别在传输层上一层的应用层中所要进行处理的具体程序。
端口号定义
数据链路层中的地址指的是MAC地址,网络层 (IP层) 中的地址,指的是IP地址。前者用来识别同一链路中不同的计算机,后者用来识别TCP/IP网络中互连的主机和路由器。
传输层也有类似概念,就是端口号。端口号用来识别同一台计算机中进行通信的不同应用程序。因此,它也被称为程序地址。
进程在网络通信中的ID识别
TCP/IP或UDP/IP通信中通常采用5个信息来识别一对通信中的进程。它们是“源IP地址”、“目标IP地址”、“协议号”、“源端口号”、“目标端口号”。其中“源IP地址”、“目标IP地址”、“协议号”在IP首部指定,而“源端口号”、“目标端口号”在TCP/UDP首部指定,只要其中某一项不同,则被认为是其他通信。
端口号的确定
1>. 标准既定的端口号
这种方法也叫静态方法。它是指每个应用程序都有其指定的端口号。但并不是说可以随意使用任何一个端口号。每个端口号都有其对应的使用目的。如,HTTP、TELNET、FTP等端口号就是固定的。这些端口号被称之为知名端口号(Well-Known Port Number)。知名端口号一般由0到1023的数字分配而成。
2>. 时序分配法
第二种方法也叫时序(或动态地)分配法。服务器有必要确定用于监听的端口号,但是接受服务的客户端没必要确定端口号。因此,客户端应用程序可以完全不用自己设置端口号,而全权交给操作系统进行分配。动态分配的端口号取值范围在49152到65535之间。
端口号与协议
端口号由其使用的传输层协议决定。因此,不同的传输协议可以使用相同的端口号。例如,TCP与UDP使用同一个端口号,但使用目的各不相同。
数据到达IP层后,会先检查IP首部中的协议号,再传给相应协议的模块。传给TCP或UDP去做端口号处理。就算是同一个端口号,由于传输协议是各自独立地进行处理,因此相互之间不会影响。
那些知名端口号与传输层协议并无关系,只要端口一致都将分配同一种程序进行处理。例如,53端口在TCP与UDP中都用于DNS服务(由域名确定IP地址时所用的协议),80端口用于HTTP通信。从目前看,由于HTTP通信必须使用TCP,所以UDP的80端口并未投入使用。
进程间的通信处理
服务端程序在UNIX系统当中叫做守护进程。例如HTTP的服务端程序是httpd(HTTP守护进程),而ssh的服务端程序是sshd(SSH守护进程)。UNIX中并不需要将这些守护进程逐个启动,而是启动一个可以代表它们接收客户端请求的inetd(互联网守护进程)服务程序即可。它是一种超级守护进程。该超级守护进程收到客户端请求以后会创建(fork)新的进程并转换(exec)为sshd等各个守护进程。
确认一个请求究竟发给的是哪个服务端(守护进程),可以通过所收到数据包的目标端口号轻松识别。当收到TCP的建立连接请求时,如果目标端口为22,则转给sshd,如果是80则转给httpd。然后,这些守护进程会继续对该连接上的通信传输进行处理。
传输协议TCP、UDP通过接收数据中的目标端口识别目标处理程序。以下图为例,传输协议的数据将被传递给HTTP、TELNET以及FTP等应用层协议。
三.UDP协议和TCP协议
UDP的首部格式
首部字段只有 8 个字节,包括源端口、目的端口、长度、检验和。12 字节的伪首部是为了计算检验和临时添加的。
- 源端口号(Source Port):表示发送端端口号,字段长16位。该字段是可选项,有时可能不会设置源端口号。没有源端口号的时候该字段的值设置为0。可用于不需要返回的通信中。
- 目标端口号(Destination Port):表示接收端端口,字段长度16位。
- 包长度(Length):该字段保存了UDP首部的长度跟数据的长度之和。单位为字节(8位字节)。
- 校验和(Checksum):校验和是为了提供可靠的UDP首部和数据而设计。
校验和计算中计算UDP伪首部的理由
TCP/IP中识别一个通信的应用需要5大要素,它们分别是“源IP地址”、“目标IP地址”、“源端口”、“目标端口”、“协议号”。然而,在UDP的首部中只包含它们当中的两项(源端口和目标端口),余下的3项都包含在IP首部里。假定其他3项都被破坏?显然,这极有可能会导致应该收包的应用收不到包,不该收到包的应用却收到了包。为了避免这类问题,有必要验证一个通信中必要的5项识别码是否正确。为此,在校验和的计算中就引入和伪首部的概念。此外,IPv6中的IP首部没有检验和字段。TCP和UDP通过伪首部,得以对5项数字进行校验,从而实现即使在IP首部并不可靠的情况下仍然能够提供可靠的通信传输。
UDP校验和:
在计算校验和时,附加在UDP伪首部与UDP数据报之前。通过在最后一位增加一个“0”将全长增加16倍。此时将UDP首部的校验和字段设置为“0”。然后以16比特为单位进行1的补码和,并将所得到的1的补码和写入校验和字段。
接收主机在收到UDP数据报以后,从IP首部获知IP地址信息构造UDP伪首部,再进行校验和计算。校验和制度按的值是校验和字段以外余下部分的1的补码和。因此,包括校验和字段在内的所有数据之和结果为“16位全部为1”时,才会被认为所收到的数据时正确的。
另外,UDP也可有可能不用校验和。此时,校验和字段中填入0.这种情况下,由于不进行校验和计算,协议处理的开销(在处理实际数据之外,为了进行通信控制的处理而不得不付出的必要的消耗部分)就会降低,从而提高数据转发的速度。然而,如果UDP首部的端口号或是IP首部的IP地址遇到损坏,那么可能会对其他通信造成不好的影响。因此,在互联网中比较推荐使用校验和检查。
原码、反码、补码 :
三种表示方法均有符号位和数值位两部分,符号位都是用0表示“正”,用1表示“负”,而数值位,三种表示方法各不相同。
在计算机系统中,数值一律用补码来表示和存储。原因在于,使用补码,可以将符号位和数值域统一处理;同时,加法和减法也可以统一处理。此外,补码与原码相互转换,其运算过程是相同的,不需要额外的硬件电路。
1. 原码
原码就是符号位加上真值的绝对值, 即用第一位表示符号, 其余位表示值. 比如如果是8位二进制:
[+1]原= 0000 0001
[-1]原= 1000 0001
第一位是符号位. 因为第一位是符号位, 所以8位二进制数的取值范围就是:
[1111 1111 , 0111 1111]
即
[-127 , 127]
原码是人脑最容易理解和计算的表示方式.
2. 反码
反码的表示方法是:
正数的反码是其本身
负数的反码是在其原码的基础上, 符号位不变,其余各个位取反.
[+1] = [00000001]原= [00000001]反
[-1] = [10000001]原= [11111110]反
可见如果一个反码表示的是负数, 人脑无法直观的看出来它的数值. 通常要将其转换成原码再计算.
3. 补码
补码的表示方法是:
正数的补码就是其本身
负数的补码是在其原码的基础上, 符号位不变, 其余各位取反, 最后+1. (即在反码的基础上+1)
[+1] = [00000001]原= [00000001]反= [00000001]补
[-1] = [10000001]原= [11111110]反= [11111111]补
对于负数, 补码表示方式也是人脑无法直观看出其数值的. 通常也需要转换成原码在计算其数值.
TCP首部格式
TCP中没有表示包长度和数据长度的字段。可由IP层获知TCP的包长,由TCO的包长可知数据的长度。
- 序号 :字段长32位,用于对字节流进行编号,例如序号为 301,表示第一个字节的编号为 301,如果携带的数据长度为 100 字节,那么下一个报文段的序号应为 401。序列号不会从0或1开始,而是建立连接时由计算机生成的随机数作为其初始值,通过SYN包传给接收端主机。此外,在建立连接和断开连接时发送的SYN包和FIN包虽然并不携带数据,但是也会作为一个字节增加对应的序列号。
- 确认号 :字段长度32位,是指期望收到的下一个报文段的序号。例如 B 正确收到 A 发送来的一个报文段,序号为 501,携带的数据长度为 200 字节,因此 B 期望下一个报文段的序号为 701,B 发送给 A 的确认报文段中确认号就为 701。
- 数据偏移 :该字段长32位,指的是数据部分距离报文段起始处的偏移量,实际上指的是首部的长度。
- 控制位(Control Flag):字段长为8位,每一位从左至右分别为CWR、ECE、URG、ACK、PSH、RST、SYN、FIN。这些控制标志也叫作控制位。
- CWR(Congestion Window Reduced) :CWR标志与后面的ECE标志都用于IP首部的ECN字段。ECE标志为1时,则通知对方已将拥塞窗口缩小。
- ECE(ECN-Echo) :ECE标志表示ECN-Echo。置为1会通知通信对方,从对方到这边的网络有拥塞。在收到数据包的IP首部中ECN为1时将TCP首部中的ECE设置为1。
- URG(Urgent Flag) :该位为1时,确认应答的字段变为有效。TCP规定除了最初建立连接时的SYN包之外该位必须设置为1。
- PSH(Push Flag) :该位为1时,表示需要将受到的数据立即传给上层应用协议。PSH为0时,则不需要立即传而是先进性缓存。
- RST(Reset Flag) :该位为1时表示TCP连接中出现异常必须强制断开连接。
- SYN(Synchronize Flag) :用于初次建立连接,在连接建立时用来初始化序号字段.SYN=1 表示希望建立连接,并在其序号的字段进行序号初始值的设定。当 SYN=1,ACK=0 时表示这是一个连接请求报文段。若对方同意建立连接,则响应报文中 SYN=1,ACK=1。
- FIN(Fin Flag) :用来释放一个连接,当 FIN=1 时,表示此报文段的发送方的数据已发送完毕,今后不会再有数据发送,希望释放连接。
- 确认 ACK :当 ACK=1 时表示确认号字段存在。TCP 规定,在连接建立后所有传送的报文段都必须把 ACK 置 1,此时确认号存在。
- 窗口 :该字段长为16位,窗口值作为接收方让发送方设置其发送窗口的依据。之所以要有这个限制,是因为接收方的数据缓存空间是有限的。TCP不允许发送超过此处所示大小的数据。不过,如果窗口为0,则表示可以发送窗口探测,以了解最新的窗口大小。但这个数据必须是1个字节。
- 校验和:TCP的校验和与UDP相似,区别在于TCP的校验和无法关闭。 TCP和UDP一样在计算校验和的时候使用TCP伪首部。
TCP和UDP的伪首部 :
伪首部(pseudo header),通常有TCP伪首部和UDP伪首部。在UDP/TCP伪首部中,包含32位源IP地址,32位目的IP地址,8位填充0,8位协议,16位TCP/UDP长度。通过伪首部的校验,UDP可以确定该数据报是不是发给本机的,通过首部协议字段,UDP可以确认有没有误传。
伪首部并非TCP/UDP数据报中实际的有效成分。伪首部是一个虚拟的数据结构,其中的信息是从数据报所在IP分组头的分组头中提取的,既不向下传送也不向上递交,而仅仅是为计算校验和。
TCP的三次握手
假设 A 为客户端,B 为服务器端
- 首先 B 处于 LISTEN(监听)状态,等待客户的连接请求。
- A 向 B 发送连接请求报文,SYN=1,ACK=0,选择一个初始的序号 x。
- B 收到连接请求报文,如果同意建立连接,则向 A 发送连接确认报文,SYN=1,ACK=1,确认号为 x+1,同时也选择一个初始的序号 y。
- A 收到 B 的连接确认报文后,还要向 B 发出确认,确认号为 y+1,序号为 x+1。
- B 收到 A 的确认后,连接建立。
三次握手的原因:
第三次握手是为了防止失效的连接请求到达服务器,让服务器错误打开连接。
客户端发送的连接请求如果在网络中滞留,那么就会隔很长一段时间才能收到服务器端发回的连接确认。客户端等待一个超时重传时间之后,就会重新请求连接。但是这个滞留的连接请求最后还是会到达服务器,如果不进行三次握手,那么服务器就会打开两个连接。如果有第三次握手,客户端会忽略服务器之后发送的对滞留连接请求的连接确认,不进行第三次握手,因此就不会再次打开连接。
TCP的四次挥手
以下描述不讨论序号和确认号,因为序号和确认号的规则比较简单。并且不讨论 ACK,因为 ACK 在连接建立之后都为 1。
- A 发送连接释放报文,FIN=1。
- B 收到之后发出确认,此时 TCP 属于半关闭状态,B 能向 A 发送数据但是 A 不能向 B 发送数据。
- 当 B 不再需要连接时,发送连接释放报文,FIN=1。
- A 收到后发出确认,进入 TIME-WAIT 状态,等待 2 MSL(最大报文存活时间)后释放连接。
- B 收到 A 的确认后释放连接。
四次挥手的原因
客户端发送了 FIN 连接释放报文之后,服务器收到了这个报文,就进入了 CLOSE-WAIT 状态。这个状态是为了让服务器端发送还未传送完毕的数据,传送完毕之后,服务器会发送 FIN 连接释放报文。
TIME_WAIT
客户端接收到服务器端的 FIN 报文后进入此状态,此时并不是直接进入 CLOSED 状态,还需要等待一个时间计时器设置的时间 2MSL。这么做有两个理由:
确保最后一个确认报文能够到达。如果 B 没收到 A 发送来的确认报文,那么就会重新发送连接释放请求报文,A 等待一段时间就是为了处理这种情况的发生。
等待一段时间是为了让本连接持续时间内所产生的所有报文都从网络中消失,使得下一个新的连接不会出现旧的连接请求报文。
TCP的 "序号/确认号" 机制
在TCP中,当发送端数据到达接受主机时,接收端主机会返回一个已收到的消息的通知。这个消息为:"ACK控制位+确认号字段"
正常的数据传输:
TCP通过ACK控制位实现可靠的数据传输。当发送端将数据发出之后会等待对端的确认应答(ACK=1)。如果有确认应答,说明数据已经成功到达对端。在一定时间内没有等到确认应答,发送端就可以认为数据已经丢失,并进行重发。由此,即使产生了丢包,仍然能够保证数据能够重新发送到对端,实现可靠传输。
未确认应答并不意味着数据一定丢失。也有可能是数据对方已经收到,只是返回的确认应答在途中丢失。
"序号/确认号" 机制
为了防止出现数据段随意重发的情况,就需要引入一种机制,它能够识别是否已经接收数据,又能判断是否需要接收。这些确认应答处理、重发控制以及重复控制等功能都可以通过序号实现。
序号是按照顺序给发送数据的每个字节都标上号码的编号(序列号的初始值并非为0,而是在建立连接以后由随机数生成,后面的计算则是对每一字节加一)。接收端查询接收数据TCP首部中序号和数据的长度,将自己下一步应该接收的序号作为确认号返送回去。这样,通过序号和确认应答号,TCP可以实现可靠传输。
TCP的数据长度并未写入TCP首部。实际通信中求得TCP包的长度的计算公式是:IP首部中的数据包长度-IP首部长度TCP首部长度。
TCP的超时重传机制
TCP 使用超时重传来实现可靠传输:如果一个已经发送的报文段在超时时间内没有收到确认,那么就重传这个报文段。
TCP要求不论处在何种网络环境下都要提供高性能通信,并且无论网络拥堵情况发生何种变化,都必须保持这一特性。为此,它在每次发包时都会计算往返时间(RTT Round Trip Time 指报文段的往返时间)及偏差(RTT时间波动的值,方差。有时也叫抖动)。将这个往返时间和偏差相加重发超时的时间,就是比这个综合要稍大一点的值。
一个报文段从发送再到接收到确认所经过的时间称为往返时间 RTT,加权平均往返时间 RTTs 计算如下:
超时时间 RTO 应该略大于 RTTs,TCP 使用的超时时间计算如下:
其中 RTTd 为偏差。
TCP的滑动窗口机制
窗口是缓存的一部分,用来暂时存放字节流。发送方和接收方各有一个窗口,接收方通过 TCP 报文段中的窗口字段告诉发送方自己的窗口大小,发送方根据这个值和其它信息设置自己的窗口大小。
发送窗口内的字节都允许被发送,接收窗口内的字节都允许被接收。如果发送窗口左部的字节已经发送并且收到了确认,那么就将发送窗口向右滑动一定距离,直到左部第一个字节不是已发送并且已确认的状态;接收窗口的滑动类似,接收窗口左部字节已经发送确认并交付主机,就向右滑动接收窗口。
接收窗口只会对窗口内最后一个按序到达的字节进行确认,例如接收窗口已经收到的字节为 {31, 34, 35},其中 {31} 按序到达,而 {34, 35} 就不是,因此只对字节 31 进行确认。发送方得到一个字节的确认之后,就知道这个字节之前的所有字节都已经被接收,因此,即使之前的确认应答信号丢失,也不会进行重发,因为可以通过后面的确认应答进行确认.
滑动窗口的作用:
利用滑动窗口机制在保证可靠性的前提下提高传输速率.
不采用滑动窗口时,每发一个数据段都要进行一次确认应答的处理, 这样传输的缺点是,包的往返时间越长通信性能就越低。
采用滑动窗口后,处于发送窗口内的数据段无需等待确认应答就可以继续送.使得确认应答不再是以每个数据段,而是以更大的单位进行确认,转发时间将会被大幅度的缩短。
发送窗口的大小就是指无需等待确认应答而可以继续发送数据的最大值。
这个机制实现了使用缓冲区(Buffer 在此处标识临时保存收发数据的场所,通常是在计算机内存中开辟的一部分空间),对多个段同时进行确认应答的功能。
窗口机制与重发控制:
1>. 确认应答未能返回的情况 这种情况下,数据已经达到对端,是不需要进行重发的。因为,发送方得到一个字节的确认之后,就知道这个字节之前的所有字节都已经被接收,因此,即使之前的确认应答信号丢失,也不会进行重发,因为可以通过后面的确认应答进行确认.然而,在没有使用窗口控制的时候,没有收到确认应答的数据会被重发。
2>. 某个报文段丢失的情况 接收窗口只会对窗口内最后一个按序到达的字节进行确认.如下图,当某一报文段(1001~2000)丢失后,发送端会一直收到序号为1001的确认应答,这个确认应答好像在提醒发送端“我想接收的是从1001开始的数据”。因此,在窗口比较大,又出现报文段丢失的情况下,同一个序号的确认应答将会被重复不断地返回。而发送端主机如果连续3次收到同一个确认应答(之所以连续收到3次而不是两次的理由是因为,即使数据段的序号被替换两次也不会触发重发机制),就会将其所对应的数据进行重发。这种机制比之前提到的超时管理更加高效,因此也被称作高速重发控制。
高速重发控制(Fast Retransmission)
TCP的流控制
流量控制是为了控制发送方发送速率,保证接收方来得及接收的机制。
接收方发送的确认报文中的窗口字段可以用来控制发送方窗口大小,从而影响发送方的发送速率。将窗口字段设置为 0,则发送方不能发送数据,直到发送方收到窗口更新通知消息,通信才可继续,但为了避免窗口更新通知消息丢失,发送端在超时后可以发送一个窗口探测信号,此数据段仅含一个字节以获取最新的窗口大小信息。
确认报文中窗口字段的值越大,说明网络的吞吐量越高。
根据窗口大小控制流量过程示例:
当接收端收到从3001号开始的数据段后其缓冲区即满,不得不将窗口字段置为0,暂时停止接收数据。之后,发送端在收到窗口更新通知后通信才得以继续进行。如果这个窗口更新通知在传输途中丢失,可能会导致无法继续通信。为避免此类问题,发送端主机会时不时发送一个叫做窗口探测的数据段,此数据段仅含一个字节以获取最新的窗口大小信息。
TCP的拥塞控制
如果网络出现拥塞,分组将会丢失,此时发送方会继续重传,从而导致网络拥塞程度更高。因此当出现拥塞时,应当控制发送方的速率。
流量控制和拥塞控制:
两者都是用来控制发送方的发送速率的,但两者的出发点不同.流量控制是为了让接收方能来得及接收,而拥塞控制是为了降低整个网络的拥塞程度。
TCP 主要通过四个算法来进行拥塞控制:慢开始、拥塞避免、快重传、快恢复。
发送方需要维护一个叫做拥塞窗口(cwnd)的状态变量,注意拥塞窗口与发送方窗口的区别:拥塞窗口只是一个状态变量,实际决定发送方能发送多少数据的是发送方窗口。
为了便于讨论,做如下假设:
- 接收方有足够大的接收缓存,因此不会发生流量控制;
- 虽然 TCP 的窗口基于字节,但是这里设窗口的大小单位为报文段。
1>. 慢开始与拥塞避免
发送的最初执行慢开始,令 cwnd = 1,发送方只能发送 1 个报文段;当收到确认后,将 cwnd 加倍,因此之后发送方能够发送的报文段数量为:2、4、8 ...
注意到慢开始每个轮次都将 cwnd 加倍,这样会让 cwnd 增长速度非常快,从而使得发送方发送的速度增长速度过快,网络拥塞的可能性也就更高。设置一个慢开始门限 ssthresh,当 cwnd >= ssthresh 时,进入拥塞避免,每个轮次只将 cwnd 加 1。
如果出现了超时(有网络拥塞造成),则令 ssthresh = cwnd / 2,然后重新执行慢开始。
2>. 快重传与快恢复
在接收方,要求每次接收到报文段都应该对最后一个已收到的有序报文段进行确认。例如已经接收到 M1 和 M2,此时收到 M4,应当发送对 M2 的确认。
在发送方,如果收到三个重复确认,那么可以知道下一个报文段丢失,此时执行快重传,立即重传下一个报文段。例如收到三个 M2,则 M3 丢失,立即重传 M3。
在这种情况下,只是丢失个别报文段,而不是网络拥塞。因此执行快恢复,令 ssthresh = cwnd / 2 ,cwnd = ssthresh,注意到此时直接进入拥塞避免。
慢开始和快恢复的快慢指的是 cwnd 的设定值,而不是 cwnd 的增长速率。慢开始 cwnd 设定为 1,而快恢复 cwnd 设定为 ssthresh。
文章参考:学习UDP与TCP的总结