【GL003】TCP/IP 协议
目录
一、TCP/IP协议简介
二、TCP/IP协议的分层模型
2.1 OSI模型的七层框架
2.2 TCP/IP协议层(四层)
2.2.1 TCP/IP协议层与ISO模型
2.2.2 TCP/IP协议层的作用
三、TCP协议的报文格式
3.1 什么是报文
3.2 TCP报文
四、TCP的通信连接
4.1 TCP的三次握手
4.1.1 三次握手过程
4.1.2 三次握手的图解
4.2 TCP的四次挥手
4.2.1 四次挥手具体过程
4.2.2 四次挥手图解
五、疑难点
一、TCP/IP协议简介
TCP/IP(传输控制协议/互联网协议)是一组用于在计算机网络上进行通信的协议,它定义了电子设备如何在网络上交换数据。TCP/IP协议族是互联网的基础,它包括了上百个不同的协议,其中最核心的是TCP和IP两个协议。
TCP(传输控制协议):
是一种面向连接的、可靠的、基于字节流的传输层通信协议。
它确保数据包正确无误地从源传送到目的地。
TCP提供数据包排序、错误检测、重传机制等功能。
它通过三次握手建立连接,并在数据传输完成后通过四次挥手释放连接。
IP(互联网协议):
是一种无连接的、不可靠的网络层协议,负责将数据包从源传送到目的地。
IP协议不保证数据包的顺序或可靠性,它只负责将数据包发送出去。
每个数据包(称为IP数据报)都包含源IP地址和目的IP地址。
除了TCP和IP,TCP/IP协议族还包括其他重要的协议,例如:
UDP(用户数据报协议):一种无连接的传输层协议,提供比TCP更快的传输速度,但不保证数据的可靠性。
ICMP(互联网控制消息协议):用于发送错误消息和操作信息。
ARP(地址解析协议):用于将IP地址解析为MAC地址。
DNS(域名系统):用于将域名转换为IP地址。
HTTP(超文本传输协议):用于从网站传输超文本到本地浏览器。
FTP(文件传输协议):用于在网络上进行文件传输。
SMTP(简单邮件传输协议):用于发送电子邮件。
SNMP(简单网络管理协议):用于网络管理。
二、TCP/IP协议的分层模型
2.1 OSI模型的七层框架
国际标准化组织ISO为了使网络应用更为普及,推出了OSI参考模型,即开放式系统互联(Open System Interconnect)模型,一般都叫OSI参考模型。OSI模型定义了网络互连的七层框架(物理层、数据链路层、网络层、传输层、会话层、表示层、应用层),每一层实现各自的功能和协议,并完成与相邻层的接口通信。OSI模型各层的通信协议举例如下:
各层的作用:
1.应用层
应用层为操作系统或网络应用程序提供访问网络服务的接口。
应用层协议的代表包括:Telnet、FTP、HTTP、SNMP等。
2.表示层
将应用处理的信息转换为适合网络传输的格式,
或将来自下一层的数据转换为上层能够处理的格式。数据的表示、安全、压缩。
3.会话层
负责建立和断开通信连接(数据流动的逻辑通路),以及数据的分割等数据传输相关的管理。
4.传输层
管理两个节点之间的数据传输。负责可靠传输(确保数据被可靠地传送到目标地址)。
5.网络层
地址管理与路由选择, 在这一层,数据的单位称为数据包(packet)(路由器)。
6.数据链路层
互连设备之间传送和识别数据帧(交换机)。
7.物理层
以"0"、 "1"代表电压的高低,灯光的闪灭,在这一层,数据的单位称为比特(bit);
(中继器、集线器、还有我们通常说的双绞线也工作在物理层)。
2.2 TCP/IP协议层(四层)
TCP/IP协议是Internet互联网最基本的协议,其在一定程度上参考了七层ISO模型。OSI模型共有七层,从下到上分别是物理层、数据链路层、网络层、运输层、会话层、表示层和应用层。但是这显然是有些复杂的,所以在TCP/IP协议中,七层被简化为了四个层次。TCP/IP模型中的各种协议,依其功能不同,被分别归属到这四层之中,常被视为是简化过后的七层OSI模型。
2.2.1 TCP/IP协议层与ISO模型
2.2.2 TCP/IP协议层的作用
TCP/IP协议的应用层的主要协议有HTTP、Telnet、FTP、SMTP等,是用来读取来自传输层的数据或者将数据传输写入传输层;
传输层的主要协议有UDP、TCP,实现端对端的数据传输;
网络层的主要协议有ICMP、IP、IGMP,主要负责网络中数据包的传送等;
链路层有时也称作数据链路层或网络接口层,主要协议有ARP、RARP,通常包括操作系统中的设备驱动程序和计算机中对应的网络接口卡,它们一起处理与传输媒介(如电缆或其他物理设备)的物理接口细节。
1.TCP/IP协议的应用层
应用层包括所有和应用程序协同工作,并利用基础网络交换应用程序的业务数据的协议。
一些特定的程序被认为运行在这个层上,该层协议所提供的服务能直接支持用户应用。
应用层协议包括HTTP(万维网服务)、FTP(文件传输)、SMTP(电子邮件)、SSH(安全远程登陆)、DNS(域名解析)以及许多其他协议。
2.TCP/IP协议的传输层
(1)传输层的协议,解决了诸如端到端可靠性问题,能确保数据可靠的到达目的地,甚至能保证数据按照正确的顺序到达目的地。
(2)传输层的主要功能大致如下:
为端到端连接提供传输服务;
这种传输服务分为可靠和不可靠的,其中TCP是典型的可靠传输,而UDP则是不可靠传输;
为端到端连接提供流量控制、差错控制、QoS(Quality of Service)服务质量等管理服务。
(3)传输层主要有两个性质不同的协议:TCP传输控制协议和UDP用户数据报协议。
TCP协议是一个面向连接的、可靠的传输协议,它提供一种可靠的字节流,能保证数据完整、无损并且按顺序到达。
TCP尽量连续不断地测试网络的负载并且控制发送数据的速度以避免网络过载。另外,TCP试图将数据按照规定的顺序发送。
UDP协议是一个无连接的数据报协议,是一个“尽力传递”和“不可靠”协议,
不会对数据包是否已经到达目的地进行检查,并且不保证数据包按顺序到达。
(4)总体来说,TCP协议传输效率低,但可靠性强;UDP协议传输效率高,但可靠性略低,适用于传输可靠性要求不高、体量小的数据(比如QQ聊天数据)。
3.TCP/IP协议的网络层
TCP/IP协议网络层的作用是在复杂的网络环境中为要发送的数据报找到一个合适的路径进行传输。
简单来说,网络层负责将数据传输到目标地址,目标地址可以是多个网络通过路由器连接而成的某一个地址。
另外,网络层负责寻找合适的路径到达对方计算机,并把数据帧传送给对方,网络层还可以实现拥塞控制、网际互连等功能。
网络层协议的代表包括:ICMP、IP、IGMP等。
4.TCP/IP协议的链路层
链路层有时也称作数据链路层或网络接口层,用来处理连接网络的硬件部分。
该层既包括操作系统硬件的设备驱动、NIC(网卡)、光纤等物理可见部分,还包括连接器等一切传输媒介。在这一层,数据的传输单位为比特。
其主要协议有ARP、RARP等。
三、TCP协议的报文格式
3.1 什么是报文
报文(message)是网络中交换与传输的数据单元,也是网络传输的单元。报文包含了将要发送的完整的数据信息,其长短不需一致。报文在传输过程中会不断地封装成分组、包、帧来传输,封装的方式就是添加一些控制信息组成的首部,那些就是报文头。
应用层:报文(message),一般指完整的信息,传输层实现报文交付,位于应用层的信息分组称为报文;
传输层:报文段(segment),组成报文的每个分组;
网络层:分组(packet)是网络传输中的二进制格式单元,数据包(datapacket)是TCP/IP通信协议传输中的数据单位;通过网络传输的数据基本单元,包含一个报头和数据本身,其中报头描述了数据的目的地及其与其他数据之间的关系,可以理解为数据传输的分组,我们将通过网络传输的基本数据单元称为数据报(Datagram);
链路层:帧(frame),数据链路层的协议数据单元,为了保证数据的可靠传输,把用户数据封装成帧;
物理层:PDU(bit),协议数据单元;
抓包,抓到的是传输层的包,packet/frame/Datagram/segment是存在于同条记录中的,这些是基于所在协议层的不同取了不同的名字。
3.2 TCP报文
在TCP/IP协议栈中,IP协议层只关心如何使数据能够跨越本地网络边界的问题,而不关心数据如何传输。整体TCP/IP协议栈,共同配合一起解决数据如何通过许许多多个点对点通路,顺利传输到达目的地。一个点对点通路被称为一“跳”(hop),通过TCP/IP协议栈,网络成员能够在许多“跳”的基础上建立相互的数据通路。数据帧格式如下图:
3.1 源端口号
源端口号表示报文的发送端口,占16位。源端口和源IP地址组合起来,可以标识报文的发送地址。
3.2 目的端口号
目的端口号表示报文的接收端口,占16位。目的端口和目的IP地址相结合,可以标识报文的接收地址。
TCP协议是基于IP协议的基础上传输的,TCP报文中的源端口号+源IP,与TCP报文中的目的端口号+目的IP一起,组合起来唯一性的确定一条TCP连接。
3.3 序号(Sequence Number)
TCP传输过程中,在发送端出的字节流中,传输报文中的数据部分的每一个字节都有它的编号。序号占32位,发起方发送数据时,都需要标记序号。
序号(Sequence Number)的语义与SYN控制标志(ControlBits)的值有关。
根据控制标志(Control Bits)中的SYN是否为1,序号(Sequence Number)表达不同的含义:
(1)当SYN = 1时,当前为连接建立阶段,此时的序号为初始序号ISN(Initial Sequence Number),通过算法来随机生成序号;
(2)当SYN = 0时,在数据传输正式开始时,第一个报文的序号为 ISN +1,后面的报文的序号,为前一个报文的SN值+TCP报文的净荷字节数(不包含TCP头)。
比如,如果发送端发送的一个TCP帧的净荷为12byte,序号为5,则发送端接着发送的下一个数据包的时候,序号的值应该设置为5+12=17。
在数据传输过程中,TCP协议通过序号对上层提供有序的数据流。
发送端可以用序号来跟踪发送的数据量;接收端可以用序号识别出重复接收到的TCP包,从而丢弃重复包;对于乱序的数据包,接收端也可以依靠序号对其进行排序。
3.4 确认序号(Acknowledgment Number)
确认序号标识了报文接收端期望接收的字节序列。
如果设置了ACK控制位,确认序号的值表示一个准备接收的包的序列码,注意,它所指向的是准备接收的包,也就是下一个期望接收的包的序列码。
举个例子,假设发送端(如Client)发送3个净荷为1000byte、起始SN序号为1的数据包给Server服务端,Server每收到一个包之后,需要回复一个ACK响应确认数据包给Client。ACK响应数据包的ACK Number值,为每个Client包的为SN+包净荷,既表示Server已经确认收到的字节数,还表示期望接收到的下一个Client发送包的SN序号,具体的ACK值如下图左边的正常传输部分所示。
左图分析:
客户端发送数据(1-1000):客户端发送了第一个数据段,包含序号1到1000的数据。
服务端发送ACK(1001):服务端接收到数据后,发送一个ACK,确认序号为1001,表示服务端已经成功接收了序号1到1000的数据,并期望接收下一个字节序号为1001的数据。
客户端发送数据(1001-2000):客户端收到ACK后,继续发送下一段数据,包含序号1001到2000的数据。
服务端发送ACK(2001):服务端接收到第二段数据后,发送ACK,确认序号为2001。
客户端发送数据(2001-3000):客户端发送第三段数据,包含序号2001到3000的数据。
服务端发送ACK(3001):服务端接收到第三段数据后,发送ACK,确认序号为3001。
右图分析:
如果发生错误,假设Server在处理Client的第二个发送包异常;
Server仍然回复一个ACK Number值为1001的确认包;
则Client的第二个数据包需要重复发送,具体的ACK值如上图右边的正常传输部分所示。
总结:只有控制标志的ACK标志为1时,数据帧中的确认序号ACK Number才有效。TCP协议规定,连接建立后,所有发送的报文的ACK必须为1,也就是建立连接后,所有报文的确认序号有效。如果是SYN类型的报文,其ACK标志为0,故没有确认序号。
3.5 头部长度
该字段占用4位(1111/15),用来表示TCP报文首部的长度,单位是4bit位。其值所表示的并不是字节数,而是头部的所含有的32bit的数目(或者倍数),或者4个字节的倍数,所以TCP头部最多可以有60字节(4*15=60)。没有任何选项字段的TCP头部长度为20字节,所以其头部长度为5,可以通过20/4=5计算得到。
3.6 预留6位
头部长度后面预留的字段长度为6位,作为保留字段,暂时没有什么用处。
3.7 控制标志
控制标志(Control Bits)共6个bit位,具体的标志位为:URG、ACK、PSH、RST、SYN、FIN。6个标志位的说明,如下图所示。
3.8 窗口大小
长度为16位,共2个字节。此字段用来进行流量控制。流量控制的单位为字节数,这个值是本端期望一次接收的字节数。例如,假如确认号是 701 ,窗口字段是 1000。这就表明,从 701 号算起,发送此报文段的一方还有接收 1000 (字节序号是 701 ~ 1700) 个字节的数据的接收缓存空间。
3.9 校验和
长度为16位,共2个字节。对整个TCP报文段,即TCP头部和TCP数据进行校验和计算,接收端用于对收到的数据包进行验证。
3.10 紧急指针
长度为16位,2个字节。它是一个偏移量,和SN序号值相加表示紧急数据最后一个字节的序号。当TCP的发送方有紧急数据需要立即发送给接收方时,它会设置TCP头部的URG(紧急)标志位。
紧急数据可以是任何类型的数据,但通常用于传输控制信息,如中断信号或数据流的紧急部分。紧急指针位于TCP头部的校验和字段之后,它是一个16位的字段,指向数据字段中紧急数据的最后一个字节的下一个字节。
紧急指针的值是相对于当前序列号的偏移量。如果序列号为S
,紧急指针为U
,则紧急数据的范围是从S
到S+U-1
。
紧急数据的范围是从序列号S开始,到序列号S+U-1结束。这意味着紧急数据占据了从S到S+U-1的序列号范围。例如,如果序列号S是100,紧急指针U是20,那么紧急数据的范围就是从序号100到序号119(100+20-1)。
3.11 可选项和填充部分
可选项和填充部分的长度为4n字节(n是整数),该部分是根据需要而增加的选项。
如果不足4n字节,要加填充位,使得选项长度为32位(4字节)的整数倍,具体的做法是在这个字段中加入额外的零,以确保TCP头是32位(4字节)的整数倍。
最常见的选项字段是MSS(Maximum SegmentSize最长报文大小),
每个连接方通常都在通信的第一个报文段(SYN标志为1的那个段)中指明这个选项字段,表示当前连接方所能接受的最大报文段的长度。
由于可选项和填充部分不是必须的,所以TCP报文首部最小长度为20个字节。
总结:
以上就是TCP报文首部的全部字段
总体来说,TCP协议的可靠性,主要通过以下几点来保障:
(1)应用数据分割成TCP认为最适合发送的数据块。这部分是通过MSS(最大数据包长度)选项来控制的,通常这种机制也被称为一种协商机制,MSS规定了TCP传往另一端的最大数据块的长度。值得注意的是,MSS只能出现在SYN报文段中,若一方不接收来自另一方的MSS值,则MSS就定为536字节。一般来讲,MSS值还是越大越好,这样可以提高网络的利用率。
(2)重传机制。设置定时器,等待确认包,如果定时器超时还没有收到确认包,则报文重传。
(3)对首部和数据进行校验。
(4)接收端对收到的数据进行排序,然后交给应用层。
(5)接收端丢弃重复的数据。
(6)TCP还提供流量控制,主要是通过滑动窗口来实现流量控制。
四、TCP的通信连接
TCP连接的建立时,双方需要经过三次握手,而断开连接时,双方需要经过四次分手。通常情况下,建立连接的双方,由一端打开一个监听套接字(ServerSocket)来监听来自请求方的TCP(Socket)连接,当服务器端监听开始时,必须做好准备接受外来的连接,如果监听到建立新连接的请求,会开启一个传输套接字,称之为被动打开(Passive Open)。
4.1 TCP的三次握手
4.1.1 三次握手过程
TCP连接的建立时,双方需要经过三次握手,具体过程如下:
1.第一次握手:
Client进入SYN_SENT状态,发送一个SYN帧来主动打开传输通道;
该帧的SYN标志位被设置为1,同时会带上Client分配好的SN序列号(seq);
该SN是根据时间产生的一个随机值,通常情况下每间隔4ms会加1。
除此之外,SYN帧还会带一个MSS(最大报文段长度)可选项的值,表示客户端发送出去的最大数据块的长度。
2.第二次握手:
Server端在收到SYN帧之后,会进入SYN_RCVD状态,同时返回SYN+ACK帧给Client;
主要目的在于通知Client,Server端已经收到SYN消息,现在需要进行确认。
Server端发出的SYN+ACK帧的ACK标志位被设置为1,其确认序号Ack(Acknowledgment Number)值被设置为Client的seq+1;
SYN+ACK帧的SYN标志位被设置为1,SN值为Server端生成的SN序号;SYN+ACK帧的MSS(最大报文段长度)表示的是Server端的最大数据块长度。
3.第三次握手:
Client在收到Server的第二次握手SYN+ACK确认帧之后,
首先将自己的状态会从SYN_SENT变成ESTABLISHED,表示自己方向的连接通道已经建立成功,Client可以发送数据给Server端了。
然后,Client发ACK帧给Server端,该ACK帧的ACK标志位被设置为1,其确认序号Ack(Acknowledgment Number)值被设置为Server端的SN序列号+1。
还有一种情况,Client可能会将ACK帧和第一帧要发送的数据,合并到一起发送给Server端。
Server端在收到Client的ACK帧之后,会从SYN_RCVD状态会进入ESTABLISHED状态,至此,Server方向的通道连接建立成功,Server可以发送数据给Client,TCP的全双工连接建立完成。
4.1.2 三次握手的图解
Client和Server完成了三次握手后,双方就进入了数据传输的阶段。数据传输完成后,连接将断开,连接断开的过程需要经历四次挥手。
4.2 TCP的四次挥手
数据传输完成之后,TCP连接开始断开(或者拆接)的过程。在这个过程中连接的每个端都能独立地、主动的发起,断开的过程TCP协议使用了四次挥手操作。
4.2.1 四次挥手具体过程
1.第一次挥手:
主动断开方(客户端/服务端)向对方发送一个FIN结束请求报文;
此报文的FIN位被设置为1,并且正确设置Sequence Number(序列号)和Acknowledgment Number(确认号)。
发送完成后,主动断开方进入FIN_WAIT_1状态,这表示主动断开方没有业务数据要发送给对方,准备关闭SOCKET连接了。
2.第二次挥手:
正常情况下,在收到了主动断开方发送的FIN断开请求报文后,被动断开方会发送一个ACK响应报文;
报文的Acknowledgment Number(确认号)值为断开请求报文的Sequence Number(序列号)加1;
该ACK确认报文的含义是:“我同意你的连接断开请求”。
之后,被动断开方就进入了CLOSE-WAIT(关闭等待)状态,
TCP协议服务会通知高层的应用进程,对方向本地方向的连接已经关闭,对方已经没有数据要发送了,若本地还要发送数据给对方,对方依然会接受。
被动断开方的CLOSE-WAIT(关闭等待)还要持续一段时间,也就是整个CLOSE-WAIT状态持续的时间。
主动断开方在收到了ACK报文后,由FIN_WAIT_1转换成FIN_WAIT_2状态。
3.第三次挥手:
在发送完成ACK报文后,被动断开方还可以继续完成业务数据的发送,待剩余数据发送完成后,或者CLOSE-WAIT(关闭等待)截止后,
被动断开方会向主动断开方发送一个FIN+ACK结束响应报文,表示被动断开方的数据都发送完了,然后,被动断开方进入LAST_ACK状态。
4.第四次挥手:
主动断开方收在到FIN+ACK断开响应报文后,还需要进行最后的确认,向被动断开方发送一个ACK确认报文,
然后,自己就进入TIME_WAIT状态,等待超时后最终关闭连接。
处于TIME_WAIT状态的主动断开方,在等待完成2MSL的时间后,如果期间没有收到其他报文,则证明对方已正常关闭,主动断开方的连接最终关闭。
被动断开方在收到主动断开方的最后的ACK报文以后,最终关闭了连接,自己啥也不管了。
4.2.2 四次挥手图解
PS:处于TIME_WAIT状态的主动断开方,在等待完成2MSL的时间后,才真正关闭连接通道,其等待的时间为什么是2MSL呢?
2MSL翻译过来就是两倍的MSL。MSL全称为Maximum Segment Lifetime,指的是一个TCP报文片段在网络中最大的存活时间,具体来说,2MSL对应于一次消息的来回(一个发送和一个回复)所需的最大时间。如果直到2MSL,主动断开方都没有再一次收到对方的报文(如FIN报文),则可以推断ACK已经被对方成功接收,此时,主动断开方将最终结束自己的TCP连接。所以,TCP的TIME_WAIT状态也称为2MSL等待状态。
有关MSL的具体的时间长度,在RFC1122协议中推荐为2分钟。在SICS(瑞典计算机科学院)开发的一个小型开源的TCP/IP协议栈——LwIP开源协议栈中MSL默认为1分钟。在源自Berkeley的TCP协议栈实现中MSL默认长度为30秒。总体来说,TIME_WAIT(2MSL)等待状态的时间长度,一般维持在1-4分钟之间。
五、疑难点
难点1:如果已经建立了连接,但是Client端突然出现故障了怎么办?
TCP还设有一个保活计时器,Client端如果出现故障,Server端不能一直等下去,这样会浪费系统资源。每收到一次Client客户端的数据帧后,Server端都的保活计时器会复位。计时器的超时时间通常是设置为2小时,若2小时还没有收到Client端的任何数据帧,Server端就会发送一个探测报文段,以后每隔75秒钟发送一次。若一连发送10个探测报文仍然没反应,Server端就认为Client端出了故障,接着就关闭连接。如果觉得保活计时器的两个多小时的间隔太长,可以自行调整TCP连接的保活参数。
难点2:为什么主动断开方在TIME-WAIT状态必须等待2MSL的时间?
(1)主动断开方等待2MSL的时间,是为了确保两端都能最终关闭。假设网络是不可靠的,被动断开方发送FIN+ACK报文后,其主动方的ACK响应报文有可能丢失,这时候的被动断开方处于LAST-ACK状态的,由于收不到ACK确认被动方一直不能正常的进入CLOSED状态。在这种场景下,被动断开方会超时重传FIN+ACK断开响应报文,如果主动断开方在2MSL时间内,收到这个重传的FIN+ACK报文,会重传一次ACK报文,后再一次重新启动2MSL计时等待,这样,就能确保被动断开方能收到ACK报文,从而能确保被动方顺利进入到CLOSED状态。只有这样,双方都能够确保关闭。反过来说,如果主动断开方在发送完ACK响应报文后,不是进入TIME_WAIT状态去等待2MSL时间,而是立即释放连接,则将无法收到被动方重传的FIN+ACK报文,所以不会再发送一次ACK确认报文,此时处于LAST-ACK状态的被动断开方,无法正常进入到CLOSED状态。
(2)防止“旧连接的已失效的数据报文”出现在新连接中。主动断开方在发送完最后一个ACK报文后,再经过2MSL,才能最终关闭和释放端口,这就意味着,相同端口的新TCP新连接,需要在2MSL的时间之后,才能够正常的建立。2MSL这段时间内,旧连接所产生的所有数据报文,都已经从网络中消失了,从而,确保了下一个新的连接中不会出现这种旧连接请求报文。
难点3:为什么连接建立的时候是三次握手,可以改成两次握手吗?
三次握手完成两个重要的功能:一是双方都做好发送数据的准备工作,而且双方都知道对方已准备好;二是双方完成初始SN序列号的协商,双方的SN序列号在握手过程中被发送和确认。如果把三次握手改成两次握手,可能发生死锁。两次握手的话,缺失了Client的二次确认ACK帧,假想的TCP建立的连接时二次挥手,可以如下图所示:
在假想的TCP建立的连接时二次握手过程中,Client发送Server发送一个SYN请求帧,Server收到后发送了确认应答SYN+ACK帧。按照两次握手的协定,Server认为连接已经成功地建立了,可以开始发送数据帧。这个过程中,如果确认应答SYN+ACK帧在传输中被丢失,Client没有收到,Client将不知道Server是否已准备好,也不知道Server的SN序列号,Client认为连接还未建立成功,将忽略Server发来的任何数据分组,会一直等待Server的SYN+ACK确认应答帧。而Server在发出的数据帧后,一直没有收到对应的ACK确认后就会产生超时,重复发送同样的数据帧。这样就形成了死锁。
难点4:为什么关闭连接的需要四次挥手,而建立连接却只要三次握手呢?
关闭连接时,被动断开方在收到对方的FIN结束请求报文时,很可能业务数据没有发送完成,并不能立即关闭连接,被动方只能先回复一个ACK响应报文,告诉主动断开方:“你发的FIN报文我收到了,只有等到我所有的业务报文都发送完了,我才能真正的结束,在结束之前,我会发你FIN+ACK报文的,你先等着”。所以,被动断开方的确认报文,需要拆开成为两步,故总体就需要四步挥手。
而在建立连接场景中,Server端的应答可以稍微简单一些。当Server端收到Client端的SYN连接请求报文后,其中ACK报文表示对请求报文的应答,SYN报文用来表示服务端的连接也已经同步开启了,而ACK报文和SYN报文之间,不会有其他报文需要发送,故而可以合二为一,可以直接发送一个SYN+ACK报文。所以,在建立连接时,只需要三次握手即可。