传输层
运输层向它上面的应用层提供通信服务。IP协议还停留在主机中的网络层,没有交付主机中的应用程序。通信的真正端点并不是主机而是主机中的进程,也就是说端到端通信是应用进程之间的通信。
运输层有一个很重要的功能——复用和分用。复用是指在发送方不同的应用进程都可以使用同一个运输层协议传递数据(当然要加上适当的首部)。分用是指接收方的运输层在剥去报文首部后能够将这些数据正确交付目的应用进程。
运输层的俩个主要协议:
(1)用户数据报协议UDP
(2)传输控制协议TCP
UDP特点
1. UDP是无连接的
发送数据之前不需要建立连接,发送数据结束之后也没有释放。
2. UDP使用尽最大努力交付
不保证可靠交付,主机不需要维护复杂的连接状态表。
3. UDP是面向报文的
发送方对应用程序交下来的报文,在添加首部之后就向下交付IP层。UDP对应用层交下来的报文既不合并也不拆分,而是保留这些报文的边界。也就是说应用层交付多长的报文,UDP就照样发送,即一次发送一个报文。
(4)UDP没有拥塞控制
这样网络出现拥塞不会使源主机的发送速率降低。允许网络在拥塞时丢失一些数据的应用是可以的。
(5)UDP支持一对一,一对多,多对一,多对多的交互通信
(6)UDP的首部开销小
只有8个字节,比TCP的20个字节的首部要短。
TCP特点
1. TCP是面向连接的运输层协议
应用程序在使用TCP协议之前必须先建立TCP连接。数据传输完之后,必须释放已经建立的连接。
2. 每一条TCP连接只能有两个端点,每一条TCP连接只能是点对点的(一对一)
3. TCP提供可靠交付的服务
通过TCP连接传送的数据,无差错、不丢失、不重复、并且按序到达。
4. TCP提供全双工通信
TCP允许通信双方的应用进程在任何时候都能发送数据。TCP的两端都有发送缓存和接收缓存。
5. 面向字节流
TCP中的“流”是指流入到进程或者从进程流出的字节序列。“面向字节流”的含义是:虽然应用程序和TCP的交互是一次一个数据块(大小不等),但是TCP把应用程序交下来的数据看成仅仅是一连串的无结构的字节流。
TCP并不关心应用程序一次把多长的报文发送到TCP的缓存中,而是根据对方给出的窗口值和当前网络的拥塞情况来决定一条报文段应包含多少字节(UDP发送的报文程度应该是应用进程给出的)。
流量控制
什么是流量控制?流量控制的目的?
流量控制是一种预防发送端过多的向接收端发送数据的机制。
如果发送者发送数据过快,接收者来不及接收,那么就会有分组丢失。为了避免分组丢失,控制发送者的发送速度,使得接收者来得及接收,这就是流量控制。流量控制根本目的是防止分组丢失,它是构成TCP可靠性的一方面。
如何实现流量控制?
由滑动窗口协议(连续ARQ协议)实现。滑动窗口协议既保证了分组无差错、有序接收,也实现了流量控制。主要的方式就是接收方返回的 ACK 中会包含自己的接收窗口的大小,并且利用大小来控制发送方的数据发送。
流量控制引发的死锁?怎么避免死锁的发生?
当发送者收到了一个窗口为0的应答,发送者便停止发送,等待接收者的下一个应答。但是如果这个窗口不为0的应答在传输过程丢失,发送者一直等待下去,而接收者以为发送者已经收到该应答,等待接收新数据,这样双方就相互等待,从而产生死锁。
为了避免流量控制引发的死锁,TCP使用了持续计时器。每当发送者收到一个零窗口的应答后就启动该计时器。时间一到便主动发送报文询问接收者的窗口大小。若接收者仍然返回零窗口,则重置该计时器继续等待;若窗口不为0,则表示应答报文丢失了,此时重置发送窗口后开始发送,这样就避免了死锁的产生。
拥塞控制
拥塞控制介绍
在计算机网络中的链路容量(即带宽)、交换结点中的缓存和处理机等,都是网络的资源。
在某段时间,若对网络中某一资源的需求超过了该资源所能提供的可用部分,网络的性能就要变坏。这种情况就叫拥塞。若网络中许多资源同时呈现供应不足,网络的性能就要明显变坏,整个网络的吞吐量将随输入负荷的增大而下降。
拥塞控制是作用于网络的,它是防止过多的数据注入到网络中,避免出现网络负载过大的情况;常用的方法就是:
- 慢开始,拥塞避免
- 快重传、快恢复。
与流量控制的区别:
流量控制是作用于接收者的,它是控制发送者的发送速度从而使接收者来得及接收,防止分组丢失的。
拥塞控制
所谓拥塞控制,就是防止过多的数据注入到网络中,这样可以使网络中的路由器或链路不至于过载。
拥塞控制都有一个前提就是:网络能够承受现有的网络负荷。拥塞控制是一个全局过程。
拥塞控制方法
1. 慢启动和避免拥塞
发送方维持一个叫做拥塞窗口cwnd(congestion window)的状态变量。拥塞窗口的大小取决于网络的拥塞程度,并且动态地在变化。发送方让自己的发送窗口等于拥塞窗口,另外考虑到接受方的接收能力,发送窗口可能小于拥塞窗口。
慢开始算法
思路:由小到大逐渐增大拥塞窗口值cwnd。从上图可以看到,一个传输轮次所经历的时间其实就是往返时间RTT,每经过一个传输轮次(发送方每收到一个 ACK),拥塞窗口值cwnd就加倍。
为了防止cwnd
增长过大引起网络拥塞,还需设置一个慢开始门限ssthresh
状态变量。ssthresh的用法如下:
- 当cwnd<ssthresh时,使用慢开始算法。
- 当cwnd>ssthresh时,改用拥塞避免算法。
- 当cwnd=ssthresh时,慢开始与拥塞避免算法任意
注意⚠️:这里的“慢”并不是指cwnd的增长速率慢,而是指在TCP开始发送报文段时先设置cwnd=1,然后逐渐增大,这当然比按照大的cwnd一下子把许多报文段突然注入到网络中要“慢得多”。
避免拥塞算法
思路:让拥塞窗口值cwnd缓慢增大,每经过一个传输轮次就加1而不是加倍。这样拥塞窗口按线性规律缓慢增长。
无论是在慢开始阶段还是在拥塞避免阶段,只要发送方判断网络出现拥塞(其根据就是没有按时收到确认,虽然没有收到确认可能是其他原因的分组丢失,但是因为无法判定,所以都当做拥塞来处理),就把慢开始门限ssthresh设置为出现拥塞时的发送窗口大小的一半(但不能小于2)。然后把拥塞窗口cwnd重新设置为1,执行慢开始算法。这样做的目的就是要迅速减少主机发送到网络中的分组数,使得发生拥塞的路由器有足够时间把队列中积压的分组处理完毕。
整个拥塞控制流程
正常流程:
发生网络用塞:
2. 快重传和快恢复
快重传
快重传要求接收方在收到一个失序的报文段后就立即发出重复确认(为的是使发送方及早知道有报文段没有到达对方,可提高网络吞吐量约20%)而不要等到自己发送数据时捎带确认。快重传算法规定,发送方只要一连收到三个重复确认就应当立即重传对方尚未收到的报文段,而不必继续等待设置的重传计时器时间到期。如下图:
快恢复
快重传配合使用的还有快恢复算法,有以下两个要点:
- 当发送方连续收到三个重复确认时,就执行“乘法减小”算法(假设拥塞时的窗口值为
cwnd
)。把ssthresh门限减半(为了预防网络发生拥塞)ssthresh = cwnd/2
。但是接下去并不执行慢开始算法 - 考虑到如果网络出现拥塞的话就不会收到好几个重复的确认,所以发送方现在认为网络可能没有出现拥塞。所以此时不执行慢开始算法,而是将cwnd设置为ssthresh减半后的值
cwnd = cwnd/2
,然后执行拥塞避免算法,使cwnd缓慢增大。如下图:TCP Reno版本是目前使用最广泛的版本。
注意:在采用快恢复算法时,慢开始算法只是在TCP连接建立时和网络出现超时时才使用
TCP/UDP 连接详解(深入理解👍)
- TCP 基本知识
- TCP三次握手与四次挥手详解 & 原因
- Socket 编程
TCP 头部格式
- 序列号:在建立连接时由计算机生成的随机数作为其初始值,通过 SYN 包传给接收端主机,每发送一次数据,就「累加」一次该「数据字节数」的大小。用来解决网络包乱序问题。
- 确认应答号:指下一次「期望」收到的数据的序列号,发送端收到这个确认应答以后可以认为在这个序号以前的数据都已经被正常接收。用来解决不丢包的问题。
控制位:
- ACK:该位为 1 时,「确认应答」的字段变为有效,TCP 规定除了最初建立连接时的 SYN 包之外该位必须设置为 1 。
- RST:该位为 1 时,表示 TCP 连接中出现异常必须强制断开连接。
- SYN:该位为 1 时,表示希望建立连接,并在其「序列号」的字段进行序列号初始值的设定。
- FIN:该位为 1 时,表示今后不会再有数据发送,希望断开连接。当通信结束希望断开连接时,通信双方的主机之间就可以相互交换 FIN 位为 1 的 TCP 段。
TCP三次握手
TCP是面向连接的,无论哪一方向另一方发送数据之前,都必须先在双方之间建立一条连接。在TCP/IP协议中,TCP协议提供可靠的连接服务,连接是通过三次握手进行初始化的。三次握手的目的是同步连接双方的序列号和确认号并交换 TCP窗口大小信息。
第一次握手:建立连接。客户端发送连接请求报文段,将SYN位置为1,Sequence Number为x;然后,客户端进入SYN_SEND状态,等待服务器的确认;
第二次握手:服务器收到SYN报文段。服务器收到客户端的SYN报文段,需要对这个SYN报文段进行确认,设置Acknowledgment Number为x+1(Sequence Number+1);同时,自己自己还要发送SYN请求信息,将SYN位置为1,Sequence Number为y;服务器端将上述所有信息放到一个报文段(即SYN+ACK报文段)中,一并发送给客户端,此时服务器进入SYN_RECV状态;
第三次握手:客户端收到服务器的SYN+ACK报文段。然后将Acknowledgment Number设置为y+1,向服务器发送ACK报文段,这个报文段发送完毕以后,客户端和服务器端都进入ESTABLISHED状态,完成TCP三次握手。
完成了三次握手,客户端和服务器端就可以开始传送数据。以上就是TCP三次握手的总体介绍。
TCP四次挥手
当客户端和服务器通过三次握手建立了TCP连接以后,当数据传送完毕,肯定是要断开TCP连接的啊。那对于TCP的断开连接,这里就有了神秘的“四次分手”。
第一次分手:主机1(可以使客户端,也可以是服务器端),设置Sequence Number和Acknowledgment Number,向主机2发送一个FIN报文段;此时,主机1进入FIN_WAIT_1状态;这表示主机1没有数据要发送给主机2了;
第二次分手:主机2收到了主机1发送的FIN报文段,向主机1回一个ACK报文段,Acknowledgment Number为Sequence Number加1;主机1进入FIN_WAIT_2状态;主机2告诉主机1,我“同意”你的关闭请求;
第三次分手:主机2向主机1发送FIN报文段,请求关闭连接,同时主机2进入LAST_ACK状态;
第四次分手:主机1收到主机2发送的FIN报文段,向主机2发送ACK报文段,然后主机1进入TIME_WAIT状态;主机2收到主机1的ACK报文段以后,就关闭连接;此时,主机1等待2MSL后依然没有收到回复,则证明Server端已正常关闭,那好,主机1也可以关闭连接了。
至此,TCP的四次分手就这么愉快的完成了。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。