IP(网络层)
Ⅰ、IP基本认识
实现主机与主机之间的通信,即点对点通信
网络层与数据链路层比较:
- MAC 的作用则是实现「直连」的两个设备之间通信,而 IP 则负责在「没有直连」的两个网络之间进行通信传输。
- 源IP地址和目标IP地址在传输过程中是不会变化的,只有源 MAC 地址和目标 MAC 一直在变化
1、IP地址的基础知识
IP 地址并不是根据主机台数来配置的,而是以网卡(接口)。像服务器、路由器等设备都是有 2 个以上的网卡,也就是它们会有 2 个以上的 IP 地址。
2、IP地址的分类
类别 | IP地址范围 | 最大主机数 |
---|---|---|
A | 0.0.0.0~127.255.255.255 | 16777214 |
B | 128.0.0.0~191.255.255.255 | 65534 |
C | 192.0.0.0~223.255.255.255 | 254 |
在IP地址中有两个特殊地址,分别是主机号全为0(指定某个网络)和全为1(指定某个网络下的所有主机,用于广播)
广播地址可以分为本地广播(在本网络内)和直接广播(在不同网络之间)
-
而 D 类和 E 类地址是没有主机号的,所以不可用于主机 IP,D 类常被用于多播(多播用于将包发送给特定组内的所有主机。广播无法穿透路由,若想给其他网段发送同样的包,就可以使用可以穿透路由的多播),E 类是预留的分类,暂时未使用。
-
IP分类的缺点:
- 同一个网络下没有层次,缺少地址的灵活性
- 不能很好的与现实网络匹配(有的类型主机数太少,有的又太多)
3、无分类地址CIDR
将地址划分为两部分:网络号+主机号。表示形式a.b.c.d/x
,其中/x
表示前 x 位属于网络号, x 的范围是 0 ~ 32 ,这就使得 IP 地址更加具有灵活性。
子网掩码也能划分出网络号和主机号。掩码的意思就是掩盖掉主机号,剩余的就是网络号。将子网掩码和 IP 地址按位计算 与,就可得到网络号。
-
分离网络号与主机号的原因:
因为两台计算机要通讯,首先要判断是否处于同一个广播域内,即网络地址是否相同。如果网络地址相同,表明接受方在本网络上,那么可以把数据包直接发送到目标主机(不需要经过路由器)。路由器寻址工作中,也就是通过这样的方式来找到对应的网络号的,进而把数据包转发给对应的网络内。
-
子网掩码还可以进行子网划分
例如:一个C类地址——192.168.1.0,子网掩码255.255.255.192进行子网划分
两位子网可以划分成00、01、10、11四个子网,每一个子网也有网络地址和广播地址,如子网0
4、IP地址与路由控制
IP地址的网络地址这一部分是用于进行路由控制。
-
路由控制表中记录着网络地址与下一步应该发送至路由器的地址。在主机和路由器上都会有各自的路由器控制表。在发送 IP 包时,首先要确定 IP 包首部中的目标地址,再从路由控制表中找到与该地址具有相同网络地 址的记录,根据该记录将 IP 包转发给相应的下一个路由器。如果路由控制表中存在多条相同网络地址的记录,就选择相同位数最多的网络地址,也就是最长匹配。
环回地址——
127.0.0.1/localhost
。环回地址不会流向网络,环回地址是在同一台计算机上的程序之间进行网络通信时所使用的一个默认地址。
5、IP分片与重组
由于链路层的最大传输单元MTU
不尽相同,当IP数据报大于MTU
时就要进行分片。经过分片之后的IP数据包是在目标主机进行重组的,路由器不负责重组。
6、IPv4
首部和IPv6
首部
Ⅱ IP协议相关技术
- DNS——域名解析
- ARP与RARP
- DHCP——动态获取IP地址
- NAT——网络地址转换
- ICMP——互联网控制报文协议
- IGMP——因特网组管理协议
1、DNS协议
例如将www.baidu.com
转化为IP地址
- 根域的DNS服务器信息保存在互联网中的所有DNS服务器中
域名解析的流程
浏览器先看自己缓存里有没有——>没有看看操作系统缓存里有没有——>没有检查本机域名解析文件hosts
——>还是没有就会进行DNS服务器查询
2、ARP协议——由IP地址找到MAC地址 ,RARP——由MAC地址找IP地址
ARP 是借助 ARP 请求与 ARP 响应两种类型的包确定 MAC 地址的。
主机通过子网广播的形式发送ARP请求,请求中包含了待查寻的主机IP地址
所有设备收到ARP请求后都会区看看请求中的IP地址是不是自己,如果是就把自己的MAC地址塞入ARP响应包中返回给主机
-
操作系统通常会把第一次通过 ARP 获取的 MAC 地址缓存起来,以便下次直接从缓存中找到对应 IP 地址的 MAC 地址。
将打印机服务器等小型嵌入式设备接入到网络时就经常会用得到RARP。RARP通常需要架设一台RARP
服务器,在服务器上注册设备的MAC地址及IP地址。然后将设备接入网络:
- 该设备发送一条「我的 MAC 地址是
XXXX
,请告诉我,我的IP地址应该是什么」的请求信息。 - RARP 服务器接到这个消息后返回「MAC地址为
XXXX
的设备,IP地址为XXXX
」的信息给这个设备。 - 设备根据RARP的应答信息设置自己的IP地址
3、DHCP——动态获取IP地址
需要DHCP客户端和DHCP服务器,使用UDP广播信道。DHCP 客户端进程监听的是 68 端口号,DHCP 服务端进程监听的是 67 端口号。步骤如下:
- 客户端首先发起 DHCP 发现报文(DHCP DISCOVER) 的 IP 数据报,由于客户端没有 IP 地址,也不知道 DHCP 服务器的地址,所以使用的是 UDP 广播通信,其使用的广播目的地址是255.255.255.255(端口 67) 并且使用 0.0.0.0(端口 68) 作为源 IP 地址。DHCP 客户端将该 IP 数据报传递给链路层,链路层然后将帧广播到所有的网络中设备。
- DHCP 服务器收到 DHCP 发现报文时,用 DHCP 提供报文(DHCP OFFER) 向客户端做出响应。该报文仍然使用 IP 广播地址 255.255.255.255,该报文信息携带服务器提供可租约的 IP 地址、子网掩码、默认网关、DNS 服务器以及 IP 地址租用期。
- 客户端收到一个或多个服务器的 DHCP 提供报文后,从中选择一个服务器,并向选中的服务器发送 DHCP 请求报文(DHCP REQUEST)进行响应,回显配置的参数。
- 服务端用 DHCP ACK 报文对 DHCP 请求报文进行响应,应答所要求的参数。
如果 DHCP 服务器和客户端不是在同一个局域网内,路由器又不会转发广播包,那不是每个网络都要配一个 DHCP 服务器?,为了解决这一问题,就出现了 DHCP 中继代理。有了 DHCP 中继代理以后,对不同网段的 IP 地址分配也可以由一个 DHCP 服务器统一进行管理。
4、NAT——网络地址转换,NAPT——网络地址与端口转换
普通的NAT转换没啥意义,要把IP地址+端口号一起转换,及NAPT
NAT/NAPT缺点
- 外部无法主动与NAT内部服务器建立连接
- 转换表的生成与转换操作都会产生性能开销
- 通信过程中,如果NAT路由器重启了,所有的 TCP连接都会被重置
解决办法:
IPv6
-
NAT穿透技术
它能够让网络应用程序主动发现自己位于 NAT 设备之后主动
获得 NAT 设备的公有 IP,并为自己建立端口映射条目也就是说,在 NAT 穿透技术中,NAT设备后的应用程序处于主动地位,它已经明确地知道 NAT 设备要修改它外发的数据包,于是它主动配合 NAT 设备的操作,主动地建立好映射,这样就不像以前由 NAT设备来建立映射了。
5、ICMP(Internet Control Message Protocol)——互联网控制报文协议
-
ICMP的功能
确认IP包是否成功送达目的地址、报告发送过程中IP包被废弃的原因和改善网络措施等等。ICMP 的这种通知消息会使用 IP 进行发送 。
-
ICMP类型
- 诊断的查询消息,即查询报文类型
- 通知出错的错误消息,即差错报文类型
6、IGMP——因特网组管理协议
- 组播(多播)地址,也就是 D 类地址,既然是组播,那就说明是只有一组的主机能收到数据包,不在一组的主机不能收到数组包,怎么管理是否是在一组呢?那么,就需要 IGMP 协议了。
IGMP协议工作在主机(组播成员)和最后一跳路由之间:
- IGMP 报文向路由器申请加入和退出组播组,默认情况下路由器是不会转发组播包到连接中的主机,除非主机通过 IGMP 加入到组播组,主机申请加入到组播组时,路由器就会记录 IGMP 路由器表,路由器后续就会转发组播包到对应的主机了。
- IGMP 报文采用 IP 封装,IP 头部的协议号为 2,而且 TTL 字段值通常为 1(只允许一跳),因为 IGMP 是工作在主机与连接的路由器之间。
-
IGMP工作机制
分为
IGMPv1
、IGMPv2
、IGMPv3
Ⅲ Ping的原理
Ping是基于ICMP协议工作的
-
源主机A先创建一个ICMP回送请求消息数据报。序号用于区分连续Ping的时候发出的多个数据报;为了计算RTT,需要加入一个发送时间
-
由 ICMP 协议将这个数据报连同地址 192.168.1.2 一起交给 IP 层。IP 层将以 192.168.1.2 作为目的地址,本机 IP 地址作为源地址,协议字段设置为 1 表示是 ICMP 协议,再加上一些其他控制信息,构建一个 IP 数据报。
加入MAC头。如果在本地 ARP 映射表中查找出 IP 地址 192.168.1.2 所对应的 MAC地址,则可以直接使用;如果没有,则需要发送 ARP 协议查询 MAC 地址,获得 MAC 地址后,由数据链路层构建一个数据帧。
主机B收到这个数据帧后,检查目的MAC地址和本机的MAC地址是否一样,一样则接受,不一样就丢弃
-
主机B构建一个ICMP回送响应消息数据报,回送响应数据包的类型字段为 0 ,序号为接收到的请求数据报中的序号,然后再发送出去给主机 A。
在规定的时候间内,源主机如果没有接到 ICMP 的应答包,则说明目标主机不可达;如果接收到了ICMP 回送响应消息,则说明目标主机可达。此时,源主机会检查,用当前时刻减去该数据包最初从源主机上发出的时刻,就是 ICMP 数据包的时间延迟。
ping 这个程序是使用了 ICMP 里面的 ECHO REQUEST(类型为 8 ) 和ECHO REPLY (类型为 0)。
Ping不通如何排错?客户端->网关->DNS->客户端(拿着解析出来的IP)->目标服务器
- ping网关,如果不通:
- 查看本地IP地址
ifconfig
,看是否没连上网 - 查看路由表
route -n
是否有相同网段的两块网卡,如果有,肯定有问题
- 查看本地IP地址
- 主机能Ping通,域名Ping不通
- 说明域名解析器出现了问题,要添加正确的DNS服务器或者启用自动分配DNS
- 解析完成后,连不上该主机
- 防火墙问题
- 目标主机禁止Ping,也就是关闭了ICMP
- 主机宕机了
Ⅳ 输入一个网址后发生了什么
- 浏览器检测地址是否合法
- DNS域名解析
- 建立TCP连接(三次握手)
- 发送HTTP请求(回车是GET请求)
- 服务器处理请求并返回HTTP报文
- 浏览器解析渲染页面
- 结束连接(四次挥手)
Ⅴ TCP三次握手四次挥手
1、TCP基本认识
① TCP头格式
序列号:在建立连接时由计算机生成的随机数作为其初始值,通过 SYN 包传给接收端主机,每发送一次数据,就「累加」一次该「数据字节数」的大小。用来解决网络包乱序问题。
确认应答号:指下一次「期望」收到的数据的序列号,发送端收到这个确认应答以后可以认为在这个序号以前的数据都已经被正常接收。用来解决不丢包的问题。
-
控制位:
- ACK:该位为 1 时,「确认应答」的字段变为有效,TCP 规定除了最初建立连接时的 SYN包之外该位必须设置为 1 。
- RST:该位为 1 时,表示 TCP 连接中出现异常必须强制断开连接。
- SYN:该位为 1 时,表示希望建立连接,并在其「序列号」的字段进行序列号初始值的设定。
- FIN:该位为 1 时,表示今后不会再有数据发送,希望断开连接。当通信结束希望断开连接时,通信双方的主机之间就可以相互交换 FIN 位为 1 的 TCP 段。
② TCP工作在运输层
③ 什么是TCP?
TCP 是面向连接的、可靠的、基于字节流的传输层通信协议。
- 面向连接:必须【一对一】才能连接,不能像UDP协议可以一对多
- 可靠:无论的网络链路中出现了怎样的链路变化,TCP 都可以保证一个报文一定能够到达接收端
- 字节流:消息是「没有边界」的,所以无论我们消息有多大都可以进行传输。并且消息是「有序的」,当「前一个」消息没有收到的时候,即使它先收到了后面的字节,那么也不能扔给应用层去处理,同时对「重复」的报文会自动丢弃。
④ 什么是TCP连接?
用于保证可靠性和流量控制维护的某些状态信息,这些信息的组合,包括Socket、序列号和窗口大小称为连接。
- Socket:由IP地址和端口号组成
- 序列号:解决乱序问题
- 窗口大小:做流量控制
⑤ 如何唯一确定一个TCP连接?
- 源地址和目的地址的字段(32位)是在 IP 头部中,作用是通过 IP 协议发送报文给对方主机。
- 源端口和目的端口的字段(16位)是在 TCP 头部中,作用是告诉 TCP 协议应该把报文发给哪个进程。
⑥ UDP和TCP有什么区别?应用场景?
UDP 不提供复杂的控制机制,利用 IP 提供面向「无连接」的通信服务。
UDP 协议真的非常简,头部只有 8 个字节( 64 位),UDP 的头部格式如下:
区别:
- TCP需要先建立连接,UDP不需要
- TCP是一对一,UDP支持一对一、一对多、多对多
- TCP是可靠交付数据,数据无差错、不丢失、不重复、按需到达;UDP交付不可靠
- TCP有拥塞控制和流量控制机制,保证数据传输的安全;UDP则没有
- TCP首部开销大,UDP只有8字节,开销小
- TCP是流式传输没有边界;UDP是一个包一个包的发送,有边界,可能会丢包或者乱序
应用场景:
- TCP是面向连接的可靠传输,可以用于FTP文件传输、HTTP/HTTPS
- UDP面向无连接,用于DNS、SNMP、视频直播音频、广播通信
⑦ 为什么UDP头部没有首部长度字段?
因为TCP头部是可变长的,而UDP头部是固定的
2、TCP连接的建立
① TCP三次握手过程和状态变迁
第三次握手是可以携带数据的,前两次握手是不可以携带数据的
② Linux下查看TCP状态
netstat-napt
命令
③ 为什么是三次握手,不是两次四次?
- 三次握手才可以阻止重复历史连接的初始化(主要原因)
- 为了实现可靠数据传输, TCP 协议的通信双方, 都必须维护一个序列号, 以标识发送出去的数据包中, 哪些是已经被对方收到的。 三次握手的过程即是通信双方相互告知序列号起始值, 并确认对方已经收到了序列号起始值的必经步骤
- 如果只是两次握手, 至多只有连接发起方的起始序列号能被确认, 另一方选择的序列号则得不到确认
- 四次握手没有必要了,冗余
④ IP层会分片,为什么TCP层还需要MSS
呢?
那么当如果一个 IP 分片丢失,整个 IP 报文的所有分片都得重传。因为 IP 层本身没有超时重传机制,它由传输层的 TCP 来负责超时和重传。为了达到最佳的传输效能 TCP 协议在建立连接的时候通常要协商双方的 MSS 值,当 TCP 层发现数据超过 MSS 时,则就先会进行分片,当然由它形成的 IP 包的长度也就不会大于 MTU ,自然也就不用 IP 分片了。如果一个 TCP 分片丢失后,进行重发时也是以 MSS 为单位.
⑤ 什么是SYN洪流攻击?如何避免?
攻击者短时间伪造不同 IP 地址的 SYN 报文,服务端每接收到一个 SYN 报文,就进入SYN_RCVD
状态,但服务端发送出去的 ACK + SYN 报文,无法得到未知 IP 主机的 ACK 应答,久而久之就会占满服务端的 SYN 接收队列(未连接队列),使得服务器不能为正常用户服务。
解决方式:
修改Linux内核参数。超出处理能力时,对新的 SYN 直接回报 RST,丢弃连接
-
SYN队列满了启动Cookie
⑥ 为什么客户端和服务器端的初始序列号是不同的?
因为网络中的报文会延迟、复制重发、有可能丢失,这样会造成的不同连接之间产生相互影响,所以为了避免相互影响,客户端和服务端的初始序列号是随机且不同的。
3、TCP断开连接
① TCP四次挥手过程和状态变迁
主动关闭连接的,才有 TIME_WAIT 状态。
② 为什么需要挥手四次?
- 关闭连接时,客户端向服务端发送 FIN 时,仅仅表示客户端不再发送数据了但是还能接收数据。
- 服务器收到客户端的 FIN 报文时,先回一个 ACK 应答报文,而服务端可能还有数据需要处理和发送,等服务端不再发送数据时,才发送 FIN 报文给客户端来表示同意现在关闭连接。
服务端的 ACK 和 FIN 一般都会分开发送,从而比三次握手导致多了一次。
③为什么TIME_WAIT等待时间是2MSL
?
MSL 是 Maximum Segment Lifetime,报文最大生存时间.MSL 的单位是时间,而 TTL 是经过路由跳数。所以 MSL 应该要大于等于 TTL消耗为 0 的时间,以确保报文已被自然消亡。
TIME_WAIT 等待 2 倍的 MSL,比较合理的解释是: 网络中可能存在来自发送方的数据包,当这些发送方的数据包被接收方处理后又会向对方发送响应,所以一来一回需要等待 2 倍的时间。
2MSL
的时间是从客户端接收到 FIN 后发送 ACK 开始计时的。如果在 TIME-WAIT 时间内,因为客户端的 ACK 没有传输到服务端,客户端又接收到了服务端重发的 FIN 报文,那么 2MSL
时间将重新计时。
④为什么要有TIME_WAIT状态
-
防止旧连接的数据包被收到
经过 2
MSL
这个时间,足以让两个方向上的数据包都被丢弃,使得原来连接的数据包在网络中都自然消失,再出现的数据包一定都是新建立连接所产生的。 -
保证连接正确关闭
TIME-WAIT 作用是等待足够的时间以确保最后的 ACK 能让被动关闭方接收,从而帮助其正常关闭。
⑤ 如果已经建立了连接,客户端突然出故障怎么办?
TCP 有一个机制是保活机制。这个机制的原理是这样的:定义一个时间段,在这个时间段内,如果没有任何连接相关的活动,TCP 保活机制会开始作用,每隔一个时间间隔,发送一个探测报文,该探测报文包含的数据非常少,如果连续几个探测报文都没有得到响应,则认为当前的 TCP 连接已经死亡,系统内核将错误信息通知给上层应用程序。
Ⅵ TCP 重传、滑动窗口、流量控制、拥塞控制
1、重传机制
TCP 实现可靠传输的方式之一,是通过序列号与确认应答。
(1) 超时重传
在发送数据时,设定一个定时器,当超过指定的时间后,没有收到对方的 ACK 确认应答报文,就会重发该数据。数据包丢失、确认应答丢失。
①超时时间(RTO)如何设置?
RTT 就是数据从网络一端传送到另一端所需的时间,也就是包的往返时间。
- 当RTO较大时,重发比较慢,效率低
- RTO较小时,可能包并没有丢失就重发,增加了网络拥堵
超时重传时间 RTO 的值应该略大于报文往返 RTT 的值。RTO是一个动态变化的值,跟着网络状况的不同而发生变化。
在Linux中,每当遇到一次超时重传的时候,都会将下一次超时时间间隔设为先前值的两倍。两次超时,就说明网络环境差,不宜频繁反复发送。
(2) 快速重传
快速重传的工作方式是当收到三个相同的 ACK 报文时,会在定时器过期之前,重传丢失的报文段。
重传的时候是重传之前的一个,还是重传所有?比如对于上面的例子,是重传 Seq2
呢?还是重传Seq2、Seq3、Seq4、Seq5
呢?因为发送端并不清楚这连续的三个 ACK 2 是谁传回来的。
(3) SACK方法(选择性确认)
这种方式需要在 TCP 头部「选项」字段里加一个 SACK 的东西,它可以将缓存的地图发送给发送方,这样发送方就可以知道哪些数据收到了,哪些数据没收到,知道了这些信息,就可以只重传丢失的数据。
(4) Duplicate SACK(D-SACK)
用来告诉发送方哪些数据被重复接受了
① 例子:ACK丢包
② 网络延迟
所以「接收方」回了一个 SACK=1000~1500,因为 ACK 已经到了 3000,所以这个 SACK 是 D-SACK,表示收到了重复的包。
- 可以让「发送方」知道,是发出去的包丢了,还是接收方回应的 ACK 包丢了
- 可以知道是不是发送方的数据包被网络延迟了
- 可以知道网络中是不是把「发送方」的数据包给复制了
2、滑动窗口
有了窗口,就可以指定窗口大小,窗口大小就是指无需等待确认应答,而可以继续发送数据的最大值。
窗口的实现实际上是操作系统开辟的一个缓存空间,发送方主机在等到确认应答返回之前,必须在缓冲区中保留已发送的数据。如果按期收到确认应答,此时数据就可以从缓存区清除。
图中的 ACK 600 确认应答报文丢失,也没关系,因为可以通过下一个确认应答进行确认,只要发送方收到了 ACK 700 确认应答,就意味着 700 之前的所有数据「接收方」都收到了。这个模式就叫累计确认或者累计应答。
① 窗口大小由哪一方决定?
这个字段是接收端告诉发送端自己还有多少缓冲区可以接收数据。于是发送端就可以根据这个接收端的处理能力来发送数据,而不会导致接收端处理不过来。通常窗口的大小是由接收方的窗口大小来决定的。
② 发送方的滑动窗口
当可用窗口为0时,表明窗口在没有收到ACK确认之前就无法继续发送数据。如果收到之前发送的3236字节的ACK确认应答后,如果发送窗口的大小没有变化,则滑动窗口可以右移五个字节,即5256为可用窗口。
TCP滑动窗口使用三个指针来跟踪在四个传输类别中的每个字节。两个绝对指针+一个相对指针(偏移)
③ 接收方的滑动窗口
约等于发送窗口的大小。比如,当接收方的应用进程读取数据的速度非常快的话,这样的话接收窗口可以很快的就空缺出来
3、流量控制(基于滑动窗口)
TCP 提供一种机制可以让「发送方」根据「接收方」的实际接收能力控制发送的数据量,这就是所谓的流量控制。流量控制是避免「发送方」的数据填满「接收方」的缓存。
避免零窗口时死锁的方法:TCP为每一个连接设有一个持续计时器(persistence timer)。只要TCP连接的一方收到对方的零窗口通知,就启动持续计时器。若持续计时器设置的时间到期,就发送一个零窗口控测报文段(携1字节的数据),那么收到这个报文段的一方就重新设置持续计时器。
4、拥塞控制
有可能会因为其他主机之间的通信使得网络拥堵。在网络出现拥堵时,如果继续发送大量数据包,可能会导致数据包时延、丢失等,这时 TCP 就会重传数据,但是一重传就会导致网络的负担更重,于是会导致更大的延迟以及更多的丢包,这个情况就会进入恶性循环被不断地放大....
拥塞控制的目的就是避免「发送方」的数据填满整个网络。
① 什么是拥塞窗口?和发送窗口有什么关系?
拥塞窗口 cwnd是发送方维护的一个的状态变量,它会根据网络的拥塞程度动态变化的。我们在前面提到过发送窗口 swnd 和接收窗口 rwnd 是约等于的关系,那么由于加入了拥塞窗口的概念后,此时发送窗口的值是swnd = min(cwnd, rwnd),也就是拥塞窗口和接收窗口中的最小值。
②如何判断当前网络是否拥塞?
只要「发送方」没有在规定时间内接收到 ACK 应答报文,也就是发生了超时重传,就会认为网络出现了拥塞。
③ 如何避免拥塞?也就是拥塞控制算法
- 慢启动
- 拥塞避免
- 拥塞发生
- 快速恢复
慢启动(指数型增长):
TCP 在刚建立连接完成后,首先是有个慢启动的过程,这个慢启动的意思就是一点一点的提高发送数据包的数量。当发送方每收到一个 ACK,拥塞窗口 cwnd 的大小就会加 1。
ssthresh是慢启动门限,一般来说 ssthresh 的大小是 65535 字节:当cwnd < ssthresh时,使用慢启动算法;当cwnd >= ssthresh时会使用【拥塞避免算法】
拥塞避免算法(线性增长):
它的规则是:每当收到一个 ACK 时,cwnd 增加 1/cwnd。
拥塞发生算法:
当数据包出现重传时,意味着发生了拥塞。重传机制有超时重传和快速重传。
发生超时重传的算法:ssthresh设为cwnd/2,cwnd重置为1。接着,就重新开始慢启动,慢启动是会突然减少数据流的。一旦「超时重传」,马上回到解放前。
发生快速重传的算法:TCP 认为这种情况不严重,因为大部分没丢,只丢了一小部分。cwnd = cwnd/2,ssthresh = cwnd,进入快速恢复算法。
快速恢复算法:
一般和快速重传配合使用。在进入快速恢复之前cwnd = cwnd/2,ssthresh = cwnd。
- 拥塞窗口 cwnd = ssthresh + 3 ( 3 的意思是确认有 3 个数据包被收到了);
- 重传丢失的数据包;
- 如果再收到重复的 ACK,那么 cwnd 增加 1;
- 如果收到新数据的 ACK 后,把 cwnd 设置为第一步中的 ssthresh 的值,原因是该 ACK 确认了新的数据,说明从 duplicated ACK 时的数据都已收到,该恢复过程已经结束,可以回到恢复之前的状态了,也即再次进入拥塞避免状态;
④ 拥塞算法总结图