传输层 复习

2022-11-12 17:46:40 浏览数 (1)

为什么需要运输层呢?

代码语言:javascript复制
作用:从通信和信息处理的角度看,传输层向它上面的应用层提供通信服务,它属于面向通信部分的最高层。**网络层的IP协议能把源主机发送出的分组**,按照首部中的目的地址,送到目的主机。但两台主机上的通信,**实际上是两个进程之间的通信**,因此IP协议虽然把分组送到目的主机,但分组只是停留在主机的网络层,并没有交付到主机的应用程序中。因此 从传输层的角度,真正通信的并不是主机而是主机的进程,传输层为两主机提供端到端的通信。
传输层有两个重要功能: 复用和分用

    复用:在发送方的不同应用进程都可以使用同一个传输层协议传送数据(当然也需要加上适当的协议首部)
分用:接收方的传输层在剥去报文的首部后能够把这些数据正确交付给应用进程


与网络层的区别:

网络层为不同主机提供通信服务,传输层为不同主机的不同应用进程提供通信服务

网络层负责ip数据包的产生以及ip数据包在逻辑网络上的路由转发。

传输层提供端到端通信服务层次,提供可靠及非可靠连接。

传输层有两个主要的协议:

1.用户数据报协议UDP

2.传输控制协议TCP

UDP(用户数据报协议)概述:

1.UDP是无连接的,即在发送数据之前不需要建立连接,减少了开销和发送数据之前的时延;

2.UDP是尽最大努力交付,即不保证可靠交付,因此主机不需要维持复杂的连接状态表;

3.UDP是面向报文的。发送方的UDP对应用程序交下来的报文,在添加首部后就向下交付给IP层。UDP对应用层交下来的报文,既不合并,也不拆分,而是保留这些报文的边界。而在接收方的UDP,对IP层交上来的UDP用户数据报,在去除首部后就原封不动地交付给上层的应用进程。

4.UDP没有拥塞控制,网络上出现的拥塞不会使源主机的发送速率降低。

5.UDP支持一对一,一对多,多对一和多对多的交互通信。

6.UDP的首部开销小,其首部只有8个字节,而TCP的首部有20个字节。

UDP首部格式

1.源端口 在需要对方回信时选用。不需要时可全0

2.目的端口 在终点交付报文时必须使用

3.长度 UDP用户数据报的长度,最小值为8(仅有首部)

4.校验和 检测UDP用户数据报在传输是否有错,有错就丢弃

注意:

① 当传输层从IP层收到UDP数据包的时候,会根据首部中的目的端口,**把UDP数据报通过相应的端口,交付给最后的终点应用程序,**若端口号不正确就丢弃报文,并有ICMP发送‘端口不可达’差错报文给发送方。虽然UDP之间的通信要用到其端口号,但是由于UDP的通信是无连接的,因此不需要套接字{(IP::端口号)->为一套接字} **ICMP协议详解 ICMP协议是一个网络层协议。 一个新搭建好的网络,往往需要先进行一个简单的测试,来验证网络是否畅通;但是IP协议并不提供可靠传输。如果丢包了,IP协议并不能通知传输层是否丢包以及丢包的原因。 所以我们就需要一种协议来完成这样的功能–ICMP协议。 ICMP协议的功能 ICMP协议的功能主要有:

  1. 确认IP包是否成功到达目标地址
  2. 通知在发送过程中IP包被丢弃的原因**

那么什么是套接字呢? TCP用主机的IP地址加上主机上的端口号作为TCP连接的端点,这种端点就叫做套接字(socket)或插口。套接字用(IP地址:端口号)表示,区分不同应用程序进程间的网络通信和连接,主要有3个参数:通信的目的IP地址、使用的传输层协议(TCP或UDP)和使用的端口号。

在网络中,如何标示一个主机?使用ip地址(在网络层,一台机器当然也可以由多个网络接口,即网卡,每个结构对应一个ip地址)。 如何标示一个主机上的特定进程呢?使用ip:port,即ip地址和端口号,一般地说,每个进行网络通信的应用程序都要占用主机上的一个端口。举个例子,使用tcp进行通信,需要建立连接,比如主机a上的进程a和主机b上的进程b进行通信,a、b之间的连接如何标示?使用四元组 【其实端口不过是一种软件抽象,学术一把,呵呵】 ip:port就确定了一个socket,在一个tcp连接中,她就像一个插口,注意,叫做插口,套接字也就是类似的意版思。你把应用程序插入到这个插座,就可以和连接的另外一方对话了。至于socket命名,是有历史由来的,不过我们学网络编程,其实不必纠结权于此 ②UDP用户数据报首部检验和的计算方法有些特殊。在计算校验和时,需要在UDP数据报之前添加12字节的伪首部。该伪首部,只是临时添加的,伪首部既不向下送也不向上递交。仅仅是为了计算校验和

伪首部组成

源IP地址

2.目标IP地址

3.填充 一开始默认为0

4.协议号17 注意TCP的伪首部的协议号是6

5.UDP包长度

计算方法:

与IP数据报首部检验和的方法相似,但是UDP的检验和是把首部和数据部分一起都检验,而IP数据报的检验和只 校验IP数据报的首部

首先是把全零放入检验和字段,再把伪首部以及UDP用户数据报看成是由许多16位的字串拼接起来的。若UDP用户数据报的数据部分不是偶数个字节,则要填入一个全零的字节(但此字节不发送)。然后按照二进制反码计算出这些16位字的和,将此和的二进制取反就是检验和字段了。在接收方,要检验接受的UDP数据报是否有差错,就把收到的UDP数据包连同伪首部一起,按二进制反码求这些16位字的和。当无差错是其结果为1,若有差错,接收方就会丢弃这个UDP数据报(也可以发给上层的应用层,但是会附上差错警告)。

TCP(传输控制协议)概述

1.TCP最主要的特点:

代码语言:javascript复制
  (1)TCP是面向连接的传输层协议,因此应用程序在使用TCP协议之前,必须**先建立TCP连接**。在传送数据完毕后,必须释放已经建立的TCP连接。

  (2)每一条TCP连接只能有两个端点,**每一条TCP连接只能是点对点**。

  (3)TCP提供可靠交付的服务,通过TCP连接传送的数据,无差错,不丢失,不重复 ,**并且按序到达;**

  (4) TCP**提供全双工通信**。

  (5)TCP**面向字节流,“流”指的是流入到进程或者从进程流出的字节序列**。

 “面向字节流”含义:**应用进程与TCP的交互是一次一个数据块(大小不等),但TCP把应用进程交下来的数据仅仅看成是一连串的无结构的字节流。**

    另外:TCP与UDP在发送报文时所采用的方式完全不同。TCP并不关心应用进程一次把多长的报文发送到TCP的缓存中,而是根据对方给出的窗口值和当前网络拥塞的程度来决定一个报文段应包含多少个字节(UDP发送的报文长度是应用进程给出的)。**TCP可以根据应用进程传到TCP缓存的数据块的长度来决定是对数据块划分再传送还是等待积累足够长的字节后再构成报文段发送出去**。

TCP的连接

每一条TCP连接的两个端点,既不是主机的IP地址,也不是应用进程,更不是传输层的协议端口。而是叫套接字(socket)

每一条TCP连接位移地被通信两端的两个端点(即两个套接字)所确定;

套接字(scoket)=(IP地址::端口号)

总之TCP连接就是由协议软件所提供的一种抽象。并且同一个IP地址可以有多个不同的TCP连接。而同一个端口号也可以出现在多个不同的TCP连接中。

可靠传输的工作原理

TCP的可靠性表现在:它向应用层提供的数据是 无差错的、有序的、无丢失的,简单的说就是:TCP最终递交给应用层的数据和发送者发送的数据是一模一样的。 TCP采用了流量控制、拥塞控制、连续ARQ等技术来保证它的可靠性

PS:网络层传输的数据单元为『数据报』,传输层的数据单元为『报文段』,但为了方便起见,可以统称为『分组』。

停止等待协议(ARQ协议)

TCP保证其可靠性采用的是更为复杂的滑动窗口协议,但停止等待协议是它的简化版,为了方便理解,这里先介绍停止等待协议。

AQR协议

ARQ(Automatic Repeat reQuest)自动重传请求。 顾名思义,当请求失败时它会自动重传,直到请求被正确接收为止。这种机制保证了每个分组都能被正确接收。停止等待协议是一种ARQ协议。

停止等待协议的原理

代码语言:javascript复制
无差错的情况 
A向B每发送一个分组,都要停止发送,等待B的确认应答;A只有收到了B的确认应答后才能发送下一个分组。

分组丢失和出现差错的情况 
发送者拥有超时计时器。每发送一个分组便会启动超时计时器**,等待B的应答。若超时仍未收到应答,则A会重发刚才的分组。** 
分组出现差错:若B收到分组,但通过检查和字段发现分组在运输途中出现差错,它会直接丢弃该分组,并且不会有任何其他动作。A超时后便会重新发送该分组,直到B正确接收为止。 
分组丢失:若分组在途中丢失,B并没有收到分组,因此也不会有任何响应。当A超时后也会重传分组,直到正确接收该分组的应答为止。 
综上所述:当**分组丢失 或 出现差错 的情况下,A都会超时重传分组。**

**应答丢失 和 应答迟到 的情况** 
TCP会给每个字节都打上序号,用于判断该分组是否已经接收。 
**应答丢失**:若B正确收到分组,并已经返回应答,但应答在返回途中丢失了。此时A也收不到应答,**从而超时重传。紧接着B又收到了该分组。接收者根据序号来判断当前收到的分组是否已经接收,若已接收则直接丢弃,并补上一个确认应答。** 
**应答迟到**:若由于网络拥塞,A迟迟收不到B发送的应答,因此会超时重传。B收到该分组后,发现已经接收,便丢弃该分组,并向A补上确认应答。A收到应答后便继续发送下一个分组。但经过了很长时间后,那个失效的应答最终抵达了A,此时A可根据序号判断该分组已经接收,此时只需简单丢弃即可。

停止等待协议的注意点

代码语言:javascript复制
每发送完一个分组,该分组必须被保留,直到收到确认应答为止。
必须给每个分组进行编号。以便按序接收,并判断该分组是否已被接收。
必须设置超时计时器。每发送一个分组就要启动计时器,超时就要重发分组。
计时器的超时时间要大于应答的平均返回时间,否则会出现很多不必要的重传,降低传输效率。但超时时间也不能太长。

滑动窗口协议(连续ARQ协议)

连续ARQ协议 在ARQ协议发送者每次只能发送一个分组,在应答到来前必须等待。而连续ARQ协议的发送者拥有一个发送窗口,发送者可以在没有得到应答的情况下连续发送窗口中的分组。这样降低了等待时间,提高了传输效率。

累计确认 在连续ARQ协议中,接收者也有个接收窗口,接收者并不需要每收到一个分组就返回一个应答,可以连续收到分组之后统一返回一个应答。这样能节省流量。 TCP头部的ack字段就是用来累计确认,它表示已经确认的字节序号 1,也表示期望发送者发送的下一个分组的起始字节号。

在深入了解TCP的可靠传输问题之前,必须先了解**

TCP报文段首部的格式。

** TCP报文段首部的前20个字节是固定的,后面的4n字节是根据需要而增加的选项。因此TCP首部的最小长度是20个字节。

源端口和目的端口 各占2个字节(各16位)TCP分用功能是通过端口实现的。加上IP首部的源端IP及终端IP,唯一的确认一个TCP连接。

代码语言:javascript复制
**序号**   占4个字节。共2^32个序号;序号增加到2^32-1时,下个序号就回到0。TCP是面向字节流的,在一个TCP连接中传送的字节流中的每个字节都按顺序编号。整个要传送的字节流的起始序号必须在连接时建立,首部中的序号字段值则指的是本报文段所发送的数据的第一个字节的序号。
确认号  占4字节,是期望收到对方下一个报文段的第一个数据字节的序号。例如:**若确认号是N,则表明到序号N-1为止的所有数据都已正确收到。**
数据偏移 占4位,它支出TCP报文段的数据起始处距离TCP报文段的起始处有多远。**实际上是指出TCP报文段的首部长度。由于首部中还有长度不确定的选项字段,因此数据偏移字段是必要的**。但是“数据偏移”的单位是32位字(即以4字长的字为计算单位),因此数据因此数据偏移的最大值是60字节(15*4),这也是TCP首部的最大长度。(选项长度不能超过40字节)。
保留  占6位。保留今后使用
紧急URG   当URG字段被置1,表示本数据报的数据部分包含紧急信息,此时紧急指针有效。 紧急数据一定位于当前数据包数据部分的最前面,紧急指针标明了紧急数据的尾部。 如control c:这个命令要求操作系统立即停止当前进程。此时,这条命令就会存放在数据包数据部分的开头,并由紧急指针标识命令的位置,并URG字段被置1。
**确认ACK  ACK被置1后确认号字段才有效。 此外,TCP规定,在连接建立后传送的所有报文段都必须把ACK置1。**
推送PSH  当接收方收到PSH=1的报文后,会立即将数据交付给应用程序,而不会等到缓冲区满后再提交。 一些交互式应用需要这样的功能,降低命令的响应时间。
复位RST 当该值为1时,表示当前TCP连接出现严重问题,必须要释放重连。
**同步SYN  SYN在建立连接时使用。 当SYN=1,ACK=0时,表示当前报文段是一个连接请求报文。 当SYN=1,ACK=1时,表示当前报文段是一个同意建立连接的应答报文。**
终止FIN FIN=1表示此报文段是一个释放连接的请求报文。
窗口   占2字节。该字段用于实现TCP的流量控制。 它表示当前接收方的接收窗口的剩余容量,发送方收到该值后会将发送窗口调整成该值的大小。发送窗口的大小又决定了发送速率,所以接收方通过设置该值就可以控制发送放的发送速率。 发送方每收到一个数据报都要调整当前的发送窗口。
检验和  用于接收端检验整个数据包在传输过程中是否出错。与UDP的伪首部一样,**但是协议号改为6。**
紧急指针 占2字节。紧急指正仅在URG=1时才有意义。即使窗口为0时也可以发送紧急数据。
选项  长度可变,最长40字节。当没有使用“选项”时,TCP首部长度为20字节。TCP最初只规定了一种选项,即最大报文长度MSS。MSS是每个TCP报文段中的数据字段的最大长度。实际上,TCP报文段数据部分至少要加上40字节的首部(TCP首部 IP首部),这里还未考虑选项部分,才能组装成一个IP数据报。若选择较小的MSS长度,网络利用率就降低。就好比TCP报文段的数据部分只有一个字节,而要传到IP层,加上包装开销至少40字节。那么网络的利用率不会超过1/41.到了数据链路层还要加上一些开销。但如果TCP报文段非常长,那么到了IP层传输时就有可能要分解成很多个短数据报片。因此MSS应尽可能大些。只要在IP层传输时不需要再分片就行。但最佳的MSS是很难确定的。默认MSS是536字节长。因此所有在互联网上的主机都应能接受报文段长度是536 20=556字节。随着互联网的发展,有陆续增加了几个选项。如窗口扩大,时间戳等。还有选择确认(SACK)选项。

TCP可靠传输的实现

发送窗口的大小由接收窗口的剩余大小决定。接收者会把当前接收窗口的剩余大小写入应答TCP报文段的头部,发送者收到应答后根据该值和当前网络拥塞情况设置发送窗口的大小。发送窗口的大小是不断变化的。 发送窗口由三个指针构成:

代码语言:javascript复制
p1 
p1指向发送窗口的后沿,它后面的字节表示已经发送且已收到应答。
p2 
p2指向尚未发送的第一个字节。 
p1-p2间的字节表示已经发送,但还没收到确认应答。这部分的字节仍需保留,因为可能还要超时重发。 
p2-p3间的字节表示可以发送,但还没有发送的字节。
p3 
p3指向发送窗口的前沿,它前面的字节尚未发送,且不允许发送。

发送者每收到一个应答,后沿就可以向前移动指定的字节。此时若窗口大小仍然没变,前沿也可以向前移动指定字节。 当p2和前沿重合时,发送者必须等待确认应答。

连续ARQ的注意点

代码语言:javascript复制
同一时刻发送窗口的大小并不一定和接收窗口一样大。 
虽然发送窗口的大小是根据接收窗口的大小来设定的,但应答在网络中传输是有时间的,有可能t1时间接收窗口大小为m,但当确认应答抵达发送者时,接收窗口的大小已经发生了变化。 
此外发送窗口的大小还随网络拥塞情况影响。当网络出现拥塞时,发送窗口将被调小。

TCP标准并未规定未按序到达的字节的处理方式。但TCP一般都会缓存这些字节,等缺少的字节到达后再交给应用层处理。这比直接丢弃乱序的字节要节约带宽。

TCP标准规定接收方必须要有累计确认功能。接收方可以对多个TCP报文段同时确认,但不能拖太长时间,一般是0.5S以内。 
此外,TCP允许接收者在有数据要发送的时候捎带上确认应答。但这种情况一般较少,因为一般很少有两个方向都要发送数据的情况。

流量控制

什么是流量控制? 如果发送者发送过快,接收者来不及接收,那么就会有分组丢失。为了避免分组丢失,控制发送者的发送速度,使得接收者来得及接收,这就是流量控制。

流量控制的目的? 流量控制根本目的是防止分组丢失,它是构成TCP可靠性的一方面。

如何实现流量控制? 由滑动窗口协议(连续ARQ协议)实现。 滑动窗口协议既保证了分组无差错、有序接收,也实现了流量控制。

流量控制引发的死锁 当发送者收到了一个窗口为0的应答,发送者便停止发送,等待接收者的下一个应答。但是如果这个窗口不为0的应答在传输过程丢失,发送者一直等待下去,而接收者以为发送者已经收到该应答,等待接收新数据,这样双方就相互等待,从而产生死锁。

持续计时器

为了避免流量控制引发的死锁,TCP使用了持续计时器。每当发送者收到一个零窗口的应答后就启动该计时器。时间一到便主动发送报文询问接收者的窗口大小。若接收者仍然返回零窗口,则重置该计时器继续等待;若窗口不为0,则表示应答报文丢失了,此时重置发送窗口后开始发送,这样就避免了死锁的产生。

拥塞控制

拥塞控制 和 流量控制 的区别?

  1. 拥塞控制:拥塞控制是作用于网络的,它是

防止过多的数据注入到网络中,避免出现网络负载过大的情况

; 2. 流量控制:流量控制是作用于接收者的,它是控制发送者的发送速度从而使接收者来得及接收。 PS:拥塞控制是针对于网络而言的,它是防止往网络中写入太多分组,从而导致网络拥塞的情况;而流量控制是针对接收者的,它是通过控制发送者的发送速度保证接收者能够来得及接收。

拥塞控制的目的?

  1. 缓解网络压力
  2. 保证分组按时到达

慢开始算法 和 拥塞避免算法

代码语言:javascript复制
发送方维护一个发送窗口,发送窗口的大小取决于网络的拥塞情况和接收窗口的大小,发送窗口是动态变化的。
发送方还维护一个慢开始门限 
    发送窗口 < 慢开始门限:使用慢开始算法
    发送窗口 > 慢开始门限:使用拥塞避免算法
    发送窗口 = 慢开始门限:使用慢开始算法或拥塞避免算法
算法的具体过程: 
    通信开始时,发送方的发送窗口设为1,并发送第一个分组M1;
    接收方收到M1后,返回确认应答,此时发送方发送窗口扩大两倍,并发送M2、M3;(即,发送方每次收到确认应答后,都将发送窗口设为当前值的两倍)
    若发送窗口>慢开始门限,则使用拥塞避免算法,每次收到确认应答后都将发送窗口 1;
    若发送方出现了超时重传,则表明网络出现拥塞,此时: 
    a)慢开始门限设为当前发送窗口的一半; 
    b)发送窗口设为1; 
    c)启用拥塞避免算法; 
    PS:发送超时重传时,发送窗口有可能已经超过了慢开始门限,也有可能还没超过;此时不管何种情况,都一律启用拥塞避免算法,并执行上述三步操作!
慢开始算法的作用:慢开始算法将发送窗口从小扩大,而且按指数级扩大,从而避免一开始就往网络中注入过多的分组从而导致拥塞;它将窗口慢慢扩大的过程其实也在探测网络拥塞情况的过程,当发现出现拥塞时,及时降低发送速度,从而减缓网络拥塞。
拥塞避免算法的作用:拥塞避免算法使发送窗口以线性方式增长,而非指数级增长,从而使网络更加不容易发生拥塞。
AIMD算法(加法增大乘法减小算法) 
慢开始算法 和 拥塞避免算法 还有个名称叫做『加法增大乘法减小算法』。 
    加法增加:指的是拥塞避免算法,使得发送窗口以线性的方式增长;
    乘法减小:指的是不管当前正使用慢开始算法还是拥塞避免算法,只要发生拥塞时,慢开始门限将会变成当前窗口的一半。

快重传算法 和 快恢复算法

代码语言:javascript复制
上述慢开始算法和拥塞避免算法能保证网络出现拥塞时进行相应的处理,而快重传和快恢复是一种拥塞预防的方式,此时网络可能尚未出现拥塞,但已经有拥塞的征兆,因此得作出一些预防措施。
快重传原理:因为TCP具有累计确认的能力,因此接收者收到一个分组的时候不会立即发出应答,可能需要等待收到多个分组之后再同一发出累计确认。但快重传算法就要求,接收者如果接收到一个乱序的分组的话,就必须立即发出前一个正确分组的确认应答,这样能让发送者尽早地知道有一个分组可能丢失。
快恢复原理:当发送者收到同一个分组的三个确认应答后,就基本可以判断这个分组已经丢失了;这时候无需等待超时,直接执行『乘法减小加法增大』: 
    将慢开始门限减半;
    将发送窗口减半(不设为1);
    使用拥塞避免算法;

TCP的运输连接管理 TCP连接建立(3次握手)

所谓三次握手(Three-Way Handshake)即建立TCP连接,就是指建立一个TCP连接时,需要客户端和服务端总共发送3个包以确认连接的建立。**在socket编程中,这一过程由客户端执行connect来触发,**整个流程如下图所示:

(1)第一次握手: Client将标志位SYN置为1,随机产生一个值seq=J,并将该数据包发送给Server,Client进入SYN_SENT状态,等待Server确认。

(2)第二次握手: Server收到数据包后由标志位SYN=1知道Client请求建立连接,Server将标志位SYN和ACK都置为1,ack=J 1,随机产生一个值seq=K,并将该数据包发送给Client以确认连接请求,Server进入SYN_RCVD状态。

(3)第三次握手:

Client收到确认后,检查ack是否为J 1,ACK是否为1,如果正确则将标志位ACK置为1,ack=K 1,并将该数据包发送给Server,Server检查ack是否为K 1,ACK是否为1,如果正确则连接建立成功,Client和Server进入ESTABLISHED状态,完成三次握手,随后Client与Server之间可以开始传输数据了。

SYN攻击:

在三次握手过程中,Server发送SYN-ACK之后,收到Client的ACK之前的TCP连接称为半连接(half-open connect),此时Server处于SYN_RCVD状态,当收到ACK后,Server转入ESTABLISHED状态。SYN攻击就是Client在短时间内伪造大量不存在的IP地址,并向Server不断地发送SYN包,Server回复确认包,并等待Client的确认,由于源地址是不存在的,因此,Server需要不断重发直至超时,这些伪造的SYN包将产时间占用未连接队列,导致正常的SYN请求因为队列满而被丢弃,从而引起网络堵塞甚至系统瘫痪。SYN攻击时一种典型的DDOS攻击,检测SYN攻击的方式非常简单,即当Server上有大量半连接状态且源IP地址是随机的,则可以断定遭到SYN攻击了,使用如下命令可以让之现行:

然后连接建立,为什么要进行三次握手呢(两次确认)。 建立三次握手主要是因为A发送了再一次的确认,那么A为什么会再确认一次呢,主要是为了防止已失效的连接请求报文段又突然传送给B,从而产生了错误。

所谓“已失效的连接请求报文”是这样产生的,正常情况下,A发出连接请求,但是因为连接报文请求丢失而未收到确认,于是A再重传一次连接请求,后来收到了请求,并收到了确认,建立了连接,数据传输完毕后,就释放链接,A共发送了两次连接请求报文段,其中第一个丢失,第二个到达了B,没有“已失效的连接请求报文段”,但是还有异常情况下,A发送的请求报文连接段并没有丢失,而是在某个网络节点滞留较长时间,以致延误到请求释放后的某个时间到达B,本来是一个早已失效的报文段,但是B收到了此失效连接请求报文段后,就误以为A又重新发送的连接请求报文段,并发送确认报文段给A,同意建立连接,如果没有三次握手,那么B发送确认后,连接就建立了,而此时A没有发送建立连接的请求报文段,于是不理会B的确认,也不会给B发送数据,而B却一直等待A发送数据,因此B的许多资源就浪费了,采用三次握手的方式就可以防止这种事情发生,例如刚刚,A不理会B,就不会给B发送确认,B收不到A的确认,就知道A不要求建立连接,就不会白白浪费资源

四次挥手:

当客户A 没有东西要发送时就要释放 A 这边的连接,A会发送一个报文(没有数据),其中 FIN 设置为1, 服务器B收到后会给应用程序一个信,这时A那边的连接已经关闭,即A不再发送信息(但仍可接收信息)。 A收到B的确认后进入等待状态,等待B请求释放连接, B数据发送完成后就向A请求连接释放,也是用FIN=1 表示, 并且用 ack = u 1(如图), A收到后回复一个确认信息,并进入 TIME_WAIT 状态, 等待 2MSL 时间。

为什么要等待呢?

为了这种情况: B向A发送 FIN = 1 的释放连接请求,但这个报文丢失了, A没有接到不会发送确认信息, B 超时会重传,这时A在 WAIT_TIME 还能够接收到这个请求,这时再回复一个确认就行了。(A收到 FIN = 1 的请求后 WAIT_TIME会重新记时)

另外服务器B存在一个保活状态,即如果A突然故障死机了,那B那边的连接资源什么时候能释放呢? 就是保活时间到了后,B会发送探测信息, 以决定是否释放连接

为什么连接的时候是三次握手,关闭的时候却是四次握手? 答:因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉Client端,“你发的FIN报文我收到了”。只有等到我Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四步握手。

TCP的四次挥手过程(简言之):主动关闭方向被动关闭方发送不会再给你发数据了的信息;被动关闭方对收到的主动关闭方的报文段进行确认;被动关闭方向主动关闭方发送我也不会再给你发数据了的信息;主动关闭方再次对被动关闭方的确认进行确认。 ———————————————— 版权声明:本文为CSDN博主「iTch_nFiG」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/itch_nfig/article/details/79550811

0 人点赞