- 类 别
- 初始状态
- 别 名
- 连接终止协议
- 中文名
- 四次挥手
- 性 质
- 终止协议
-
2017-06-04 21:53:54
背景描述
通过上一篇中网络模型中的IP层的介绍,我们知道网络层,可以实现两个主机之间的通信。但是这并不具体,因为,真正进行通信的实体是在主机中的进程,是一个主机中的一个进程与另外一个主机中的一个进程在交换数据。IP协议虽然能把数据报文送到目的主机,但是并没有交付给主机的具体应用进程。而端到端的通信才应该是应用进程之间的通信。
UDP,在传送数据前不需要先建立连接,远地的主机在收到UDP报文后也不需要给出任何确认。虽然UDP不提供可靠交付,但是正是因为这样,省去和很多的开销,使得它的速度比较快,比如一些对实时性要求较高的服务,就常常使用的是UDP。对应的应用层的协议主要有 DNS,TFTP,DHCP,SNMP,NFS 等。
TCP,提供面向连接的服务,在传送数据之前必须先建立连接,数据传送完成后要释放连接。因此TCP是一种可靠的的运输服务,但是正因为这样,不可避免的增加了许多的开销,比如确认,流量控制等。对应的应用层的协议主要有 SMTP,TELNET,HTTP,FTP 等。
常用的熟知端口号
应用程序 FTP TFTP TELNET SMTP DNS HTTP SSH MYSQL 熟知端口 21,20 69 23 25 53 80 22 3306 传输层协议 TCP UDP TCP TCP UDP TCP TCP TCP
TCP的概述
TCP把连接作为最基本的对象,每一条TCP连接都有两个端点,这种断点我们叫作套接字(socket),它的定义为端口号拼接到IP地址即构成了套接字,例如,若IP地址为192.3.4.16 而端口号为80,那么得到的套接字为192.3.4.16:80。
TCP报文首部
- 源端口和目的端口,各占2个字节,分别写入源端口和目的端口;
- 序号,占4个字节,TCP连接中传送的字节流中的每个字节都按顺序编号。例如,一段报文的序号字段值是 301 ,而携带的数据共有100字段,显然下一个报文段(如果还有的话)的数据序号应该从401开始;
- 确认号,占4个字节,是期望收到对方下一个报文的第一个数据字节的序号。例如,B收到了A发送过来的报文,其序列号字段是501,而数据长度是200字节,这表明B正确的收到了A发送的到序号700为止的数据。因此,B期望收到A的下一个数据序号是701,于是B在发送给A的确认报文段中把确认号置为701;
- 数据偏移,占4位,它指出TCP报文的数据距离TCP报文段的起始处有多远;
- 保留,占6位,保留今后使用,但目前应都位0;
- 紧急URG,当URG=1,表明紧急指针字段有效。告诉系统此报文段中有紧急数据;
- 确认ACK,仅当ACK=1时,确认号字段才有效。TCP规定,在连接建立后所有报文的传输都必须把ACK置1;
- 推送PSH,当两个应用进程进行交互式通信时,有时在一端的应用进程希望在键入一个命令后立即就能收到对方的响应,这时候就将PSH=1;
- 复位RST,当RST=1,表明TCP连接中出现严重差错,必须释放连接,然后再重新建立连接;
- 同步SYN,在连接建立时用来同步序号。当SYN=1,ACK=0,表明是连接请求报文,若同意连接,则响应报文中应该使SYN=1,ACK=1;
- 终止FIN,用来释放连接。当FIN=1,表明此报文的发送方的数据已经发送完毕,并且要求释放;
- 窗口,占2字节,指的是通知接收方,发送本报文你需要有多大的空间来接受;
- 检验和,占2字节,校验首部和数据这两部分;
- 紧急指针,占2字节,指出本报文段中的紧急数据的字节数;
- 选项,长度可变,定义一些其他的可选的参数。
TCP连接的建立(三次握手)
最开始的时候客户端和服务器都是处于CLOSED状态。主动打开连接的为客户端,被动打开连接的是服务器。
- TCP服务器进程先创建传输控制块TCB,时刻准备接受客户进程的连接请求,此时服务器就进入了LISTEN(监听)状态;
- TCP客户进程也是先创建传输控制块TCB,然后向服务器发出连接请求报文,这是报文首部中的同部位SYN=1,同时选择一个初始序列号 seq=x ,此时,TCP客户端进程进入了 SYN-SENT(同步已发送状态)状态。TCP规定,SYN报文段(SYN=1的报文段)不能携带数据,但需要消耗掉一个序号。
- TCP服务器收到请求报文后,如果同意连接,则发出确认报文。确认报文中应该 ACK=1,SYN=1,确认号是ack=x+1,同时也要为自己初始化一个序列号 seq=y,此时,TCP服务器进程进入了SYN-RCVD(同步收到)状态。这个报文也不能携带数据,但是同样要消耗一个序号。
- TCP客户进程收到确认后,还要向服务器给出确认。确认报文的ACK=1,ack=y+1,自己的序列号seq=x+1,此时,TCP连接建立,客户端进入ESTABLISHED(已建立连接)状态。TCP规定,ACK报文段可以携带数据,但是如果不携带数据则不消耗序号。
- 当服务器收到客户端的确认后也进入ESTABLISHED状态,此后双方就可以开始通信了。
为什么TCP客户端最后还要发送一次确认呢?
一句话,主要防止已经失效的连接请求报文突然又传送到了服务器,从而产生错误。
如果使用的是两次握手建立连接,假设有这样一种场景,客户端发送了第一个请求连接并且没有丢失,只是因为在网络结点中滞留的时间太长了,由于TCP的客户端迟迟没有收到确认报文,以为服务器没有收到,此时重新向服务器发送这条报文,此后客户端和服务器经过两次握手完成连接,传输数据,然后关闭连接。此时此前滞留的那一次请求连接,网络通畅了到达了服务器,这个报文本该是失效的,但是,两次握手的机制将会让客户端和服务器再次建立连接,这将导致不必要的错误和资源的浪费。
如果采用的是三次握手,就算是那一次失效的报文传送过来了,服务端接受到了那条失效报文并且回复了确认报文,但是客户端不会再次发出确认。由于服务器收不到确认,就知道客户端并没有请求连接。
TCP连接的释放(四次挥手)
数据传输完毕后,双方都可释放连接。最开始的时候,客户端和服务器都是处于ESTABLISHED状态,然后客户端主动关闭,服务器被动关闭。
- 客户端进程发出连接释放报文,并且停止发送数据。释放数据报文首部,FIN=1,其序列号为seq=u(等于前面已经传送过来的数据的最后一个字节的序号加1),此时,客户端进入FIN-WAIT-1(终止等待1)状态。 TCP规定,FIN报文段即使不携带数据,也要消耗一个序号。
- 服务器收到连接释放报文,发出确认报文,ACK=1,ack=u+1,并且带上自己的序列号seq=v,此时,服务端就进入了CLOSE-WAIT(关闭等待)状态。TCP服务器通知高层的应用进程,客户端向服务器的方向就释放了,这时候处于半关闭状态,即客户端已经没有数据要发送了,但是服务器若发送数据,客户端依然要接受。这个状态还要持续一段时间,也就是整个CLOSE-WAIT状态持续的时间。
- 客户端收到服务器的确认请求后,此时,客户端就进入FIN-WAIT-2(终止等待2)状态,等待服务器发送连接释放报文(在这之前还需要接受服务器发送的最后的数据)。
- 服务器将最后的数据发送完毕后,就向客户端发送连接释放报文,FIN=1,ack=u+1,由于在半关闭状态,服务器很可能又发送了一些数据,假定此时的序列号为seq=w,此时,服务器就进入了LAST-ACK(最后确认)状态,等待客户端的确认。
- 客户端收到服务器的连接释放报文后,必须发出确认,ACK=1,ack=w+1,而自己的序列号是seq=u+1,此时,客户端就进入了TIME-WAIT(时间等待)状态。注意此时TCP连接还没有释放,必须经过2 ∗ * ∗MSL(最长报文段寿命)的时间后,当客户端撤销相应的TCB后,才进入CLOSED状态。
- 服务器只要收到了客户端发出的确认,立即进入CLOSED状态。同样,撤销TCB后,就结束了这次的TCP连接。可以看到,服务器结束TCP连接的时间要比客户端早一些。
为什么客户端最后还要等待2MSL?
MSL(Maximum Segment Lifetime),TCP允许不同的实现可以设置不同的MSL值。
第一,保证客户端发送的最后一个ACK报文能够到达服务器,因为这个ACK报文可能丢失,站在服务器的角度看来,我已经发送了FIN+ACK报文请求断开了,客户端还没有给我回应,应该是我发送的请求断开报文它没有收到,于是服务器又会重新发送一次,而客户端就能在这个2MSL时间段内收到这个重传的报文,接着给出回应报文,并且会重启2MSL计时器。
第二,防止类似与“三次握手”中提到了的“已经失效的连接请求报文段”出现在本连接中。客户端发送完最后一个确认报文后,在这个2MSL时间中,就可以使本连接持续的时间内所产生的所有报文段都从网络中消失。这样新的连接中不会出现旧连接的请求报文。
为什么建立连接是三次握手,关闭连接确是四次挥手呢?
建立连接的时候, 服务器在LISTEN状态下,收到建立连接请求的SYN报文后,把ACK和SYN放在一个报文里发送给客户端。
而关闭连接时,服务器收到对方的FIN报文时,仅仅表示对方不再发送数据了但是还能接收数据,而自己也未必全部数据都发送给对方了,所以己方可以立即关闭,也可以发送一些数据给对方后,再发送FIN报文给对方来表示同意现在关闭连接,因此,己方ACK和FIN一般都会分开发送,从而导致多了一次。如果已经建立了连接,但是客户端突然出现故障了怎么办?
TCP还设有一个保活计时器,显然,客户端如果出现故障,服务器不能一直等下去,白白浪费资源。服务器每收到一次客户端的请求后都会重新复位这个计时器,时间通常是设置为2小时,若两小时还没有收到客户端的任何数据,服务器就会发送一个探测报文段,以后每隔75秒发送一次。若一连发送10个探测报文仍然没反应,服务器就认为客户端出了故障,接着就关闭连接。
更多相关内容 -
我终于搞懂了TCP的三次握手和四次挥手(图片案例详解)
2021-01-06 09:46:19TCP三次握手和四次挥手不管是在开发还是面试中都是一个非常重要的知识点,它是我们优化web程序性能的基础。欢迎学习,一起进步 文章目录一.TCP简介二.TCP数据报结构三.TCP的三次握手四.TCP的四次挥手 一.TCP简介 TCP... -
三次握手于四次挥手.docx
2020-09-05 10:30:02基于ajax请求过程分析Http协议的三次握手和四次挥手过程。 基于ajax请求过程分析Http协议的三次握手和四次挥手过程 基于ajax请求过程分析Http协议的三次握手和四次挥手过程 基于ajax请求过程分析Http协议的三次握手... -
TCP三次握手与四次挥手.pdf
2021-04-23 12:20:43TCP三次握手与四次挥手.pdf -
tcp的三次握手和四次挥手抓包-.pcapng
2020-06-17 14:19:12用wireshark抓取的tcp的三次握手和四次挥手的包,适用于初学者了解tcp连接建立和断开的流程 -
TCP三次握手和四次挥手面试题详解.pdf
2021-04-11 10:48:37TCP 三次握手和四次挥手,面试题详解,图文并茂,欢迎技术交流 -
TCP三次握手与四次挥手报文(XShell).pcapng
2020-06-01 19:50:05通过X Shell登陆VM虚拟机抓取的三次握手及四次挥手的报文,下载后请使用WireShark软件打开,报文供大家学习使用! -
TCP/IP协议中三次握手四次挥手的原理及流程分析
2020-08-28 18:36:51主要介绍了TCP/IP协议中三次握手四次挥手的原理及流程分析,具有一定参考价值,需要的朋友可以了解下。 -
深入浅出TCP四次挥手 (多图详解)
2022-02-12 10:35:01多图详解,深入浅出TCP四次挥手前言
TCP三次握手和四次挥手是面试题的热门考点,它们分别对应TCP的连接和释放过程。在深入浅出TCP三次握手的文章中,我们详细讲解了三次握手的过程,今天我们继续深入学习TCP四次挥手,以及相关面试问题解答。
1、TCP的连接释放
- TCP 连接释放过程比较复杂。
- 数据传输结束后,通信的双方都可释放连接。
- TCP 连接释放过程是 四报文挥手。
2、TCP通过“四报文挥手”来释放连接
- TCP 连接的建立 采用客户服务器方式。
- 主动发起连接建立的应用进程叫做 TCP客户 (client)。
- 被动等待连接建立的应用进程叫做 TCP服务器 (server)。
- 任何一方都可以在数据传送结束后发出连接释放的通知。
3、四次挥手图文详解
数据传输结束后,TCP通信双方者都可以释放连接, 现在TCP客户进程和TCP服务器进程都处于连接已建立(ESTABLISHED)状态。
假设使用TCP客户进程的应用进程通知其主动关闭TCP连接。TCP客户进程会发送TCP连接释放报文段,并进入终止等待1(FIN-WAIT-1)状态。
TCP连接释放报文段首部中:
- 终止位FIN和确认为ACK的值都被设置为1,表明这是一个TCP连接释放报文段,同时也对之前收到的报文段进行确认。
- 序号seq字段的值设置为u,它等于TCP客户进程之前已传送过的数据的最后一个字节的序号加1。
- 确认号ack字段的值设置为v,它等于TCP客户进程之前已收到的、数据的最后一个字节的序号加1。
请注意: TCP规定终止位FIN等于1的报文段即使不携带数据,也要消耗掉一个序号。
TCP服务器进程收到TCP连接释放报文段后,会发送一个普通的TCP确认报文段并进入关闭等待(CLOSE-WAIT)状态。
TCP确认释放报文段首部中:
- 确认位ACK的值被设置为1,表明这是一个普通的TCP确认报文段。
- 序号seq字段的值设置为v,它等于TCP服务器进程之前已传送过的数据的最后一个字节的序号加1,这也与之前收到的TCP连接释放报文段中的确认号匹配。
- 确认号ack字段的值设置为u+1,这是对TCP连接释放报文段的确认。
TCP服务器进程应该通知高层应用进程,TCP客户进程要断开与自己的TCP连接。此时,从TCP客户进程到TCP服务器进程这个方向的连接就释放了。这时的TCP连接属于半关闭状态,也就是TCP客户进程已经没有数据要发送了。但如果TCP服务器进程还有数据要发送,TCP客户进程仍要接收,也就是说从TCP服务器进程到TCP客户进程这个方向的连接并未关闭,这个状态可能要持续一段时间。
TCP客户进程收到TCP确认报文段后就进入终止等待2(FIN-WAIT-2)状态,等待TCP服务器进程发出的TCP连接释放报文段。 若使用TCP服务器进程的应用进程已经没有数据要发送了,应用进程就通知其TCP服务器进程释放连接。由于TCP连接释放是由TCP客户进程主动发起的,因此TCP服务器进程对TCP连接的释放称为被动关闭连接。
TCP服务器进程发送TCP连接释放报文段并进入最后确认(LAST-ACK)状态。
TCP连接释放报文段首部中:
- 终止位FIN和确认位ACK的值都被设置为1,表明这是一个TCP连接释放报文段,同时也对之前收到的报文段进行确认。
- 假定序号seq字段的值为w,这是因为在半关闭状态下,TCP服务器进程可能又发送了一些数据。
- 确认号ack字段的值为u+1,这是对之前收到的TCP连接释放报文段的重复确认。
TCP客户进程收到TCP连接释放报文段后,必须针对该报文段发送普通的TCP确认报文段,之后进入时间等待(TIME-WAIT)状态。
TCP确认报文段首部中:
- 确认为ACK的值被设置为1,表明这是一个普通的TCP确认报文段。
- 序号seq字段的值设置为u+1,这是因为TCP客户进程之前发送的TCP连接释放报文段虽然不携带数据,但要消耗掉一个序号。
- 确认号ack字段的值设置为w+1,这是对所收到的TCP连接释放报文段的确认。
TCP服务器进程收到该报文段后就进入关闭状态,而TCP客户进程还要进过2MSL后才能进入关闭状态。 ( MSL(Maximum Segment Lifetime)意思是最长报文段寿命,RFC793建议为2分钟。)
4、四次挥手文字总结
四次挥手即 TCP 连接的释放,这里假设客户端主动释放连接。在挥手之前主动释放连接的客户端结束ESTABLISHED 阶段,随后开始四次挥手:
① 首先客户端向服务器发送一段 TCP 报文表明其想要释放 TCP 连接,其中:
-
标记位为 FIN,表示请求释放连接;
-
序号为 Seq = u;
-
随后客户端进入 FIN-WAIT-1 阶段,即半关闭阶段,并且停止向服务端发送通信数据。
② 服务器接收到客户端请求断开连接的 FIN 报文后,结束 ESTABLISHED 阶段,进入 CLOSE-WAIT 阶段并返回一段 TCP 报文,其中:
-
标记位为 ACK,表示接收到客户端释放连接的请求;
-
序号为 Seq = v;
-
确认号为 Ack = u + 1,表示是在收到客户端报文的基础上,将其序号值加 1 作为本段报文确认号Ack 的值;
-
随后服务器开始准备释放服务器端到客户端方向上的连接。
客户端收到服务器发送过来的 TCP 报文后,确认服务器已经收到了客户端连接释放的请求,随后客户端结束 FIN-WAIT-1 阶段,进入 FIN-WAIT-2 阶段。
③ 服务器端在发出 ACK 确认报文后,服务器端会将遗留的待传数据传送给客户端,待传输完成后即经 过 CLOSE-WAIT 阶段,便做好了释放服务器端到客户端的连接准备,再次向客户端发出一段 TCP 报文, 其中:
-
标记位为 FIN 和 ACK,表示已经准备好释放连接了;
-
序号为 Seq = w;
-
确认号 Ack = u + 1,表示是在收到客户端报文的基础上,将其序号 Seq 的值加 1 作为本段报文确认号 Ack 的值。
随后服务器端结束 CLOSE-WAIT 阶段,进入 LAST-ACK 阶段。并且停止向客户端发送数据。
④ 客户端收到从服务器发来的 TCP 报文,确认了服务器已经做好释放连接的准备,于是结束 FIN-WAIT-2 阶段,进入 TIME-WAIT 阶段,并向服务器发送一段报文,其中:
-
标记位为 ACK,表示接收到服务器准备好释放连接的信号;
-
序号为 Seq= u + 1,表示是在已收到服务器报文的基础上,将其确认号 Ack 值作为本段序号的值;
-
确认号为 Ack= w + 1,表示是在收到了服务器报文的基础上,将其序号 Seq 的值作为本段报文确认号的值。
随后客户端开始在 TIME-WAIT 阶段等待 2 MSL。服务器端收到从客户端发出的 TCP 报文之后结束LAST-ACK 阶段,进入 CLOSED 阶段。由此正式确认关闭服务器端到客户端方向上的连接。客户端等待完 2 MSL 之后,结束 TIME-WAIT 阶段,进入 CLOSED 阶段,由此完成「四次挥手」。
5、相关面试问题
1、TCP客户进程在发送完最后一个确认报文后,为什么不直接进入关闭状态?而是要进入时间等待状态,2MSL后才进入关闭状态,这是否有必要呢?
来看这种状况,TCP服务器进程发送TCP连接释放报文段后进入最后确认状态。TCP客户进程收到该报文段后,发送普通的TCP确认报文段,并进入关闭状态而不是时间等待状态。然后,该TCP确认报文段丢失了,这必然会造成TCP服务器进程对之前所发送的TCP连接释放报文段的超时重传,并仍处于最后确认状态。
重传的TCP连接释放报文段到达TCP客户进程。由于TCP客户进程属于关闭状态,因此不理睬该报文段。这必然会造成TCP服务器进程反复重传TCP连接释放报文段, 并一直处于最后确认状态而无法进入关闭状态。
因此时间等待状态以及处于该状态2MSL时长,可以确保TCP服务器进程可以收到最后一个TCP确认报文段而进入关闭状态。
另外,TCP客户进程在发送完最后一个TCP确认报文段后,在经过2MSL时长,就可以使本次连接持续时间内所产生的所有报文段都从网络中消失,这样就可以使下一个新的TCP连接中,不会出现旧连接中的报文段。
2、为什么要四次挥手?
释放 TCP 连接时之所以需要四次挥手,是因为 FIN 释放连接报文和 ACK 确认接收报文是分别在两次握手中传输的。 当主动方在数据传送结束后发出连接释放的通知,由于被动方可能还有必要的数据要处理,所以会先返回 ACK 确认收到报文。当被动方也没有数据再发送的时候,则发出连接释放通知,对方确认后才完全关闭TCP连接。
3、CLOSE-WAIT 和TIME-WAIT 的状态和意义
在服务器收到客户端关闭连接的请求并告诉客户端自己已经成功收到了该请求之后,服务器进入了CLOSE-WAIT 状态,然而此时有可能服务端还有一些数据没有传输完成,因此不能立即关闭连接,而CLOSE-WAIT 状态就是为了保证服务器在关闭连接之前将待发送的数据发送完成。
TIME-WAIT 发生在第四次挥手,当客户端向服务端发送 ACK 确认报文后进入该状态,若取消该状态,即客户端在收到服务端的 FIN 报文后立即关闭连接,此时服务端相应的端口并没有关闭,若客户端在相同的端口立即建立新的连接,则有可能接收到上一次连接中残留的数据包,可能会导致不可预料的异常出现。
4、Time_wait过多有什么危害?
内存资源占用、端口资源占用(一个TCP连接至少消耗一个端口),每端口,无法建立新连接。
服务器资源受限:服务器监听一个端口,会把连接丢给线程处理,可以继续监听端口,但是线程池处理不了那么多连接。5、Time_wait状态过多的优化?
什么时候产生: 首先调用close()发起主动关闭的一方,再发送最后一个ACK之后。
为何产生: 确保最后一个ACK到达,保证TCP全双工连接可靠释放;使旧的数据包过期消失。什么时候会产生大量Time_wait:当请求量比较大的时候,而且所有的请求都是短连接的时候。
如何避免: 多IP增加随机端口;内核参数调优(服务器设置SO_REUSEADDR套接字选项来通知内核,如果端口忙,但TCP连接位于TIME_WAIT状态时可以重用端口)﹔使用长连接(Connection: keep-
alive) 、 Linux参数net.ipv4.tcp_tw_reuse和 tcp_timestamps开启,复用处于TIME_WAIT的socket为新的连接所用。
如果我的文章对你有帮助的话,欢迎一键三连!!! -
三次握手和四次挥手详解
2020-04-08 15:46:32三次握手和四次挥手详解,觉得本博文写的很好,分享给正在学习或者学习完还对TCP的三次握手和四次挥手还不熟悉的人,相信看完之后就能明白了。 -
【Linux】TCP三次握手,四次挥手的过程
2021-01-06 18:39:24TCP三次握手,四次挥手这是一个非常重要的知识点,我也来总结一下。 关于面试最经常问的问题无非就是: 握手为什么是3次? 2次可以吗? 为什么不是4次呢? 你能不能详细的介绍一下TCP三次握手的详细过程? 能不能说... -
【图解】三次握手,四次挥手 —— 用心看这一篇就够了
2022-04-04 15:41:22本文摘要:TCP 三次握手,四次挥手知识点精析。备考、面试前看两眼,加深记忆,祝你一臂之力。顺利通过考试、拿到 offer。 如果本文帮助到你的话,还请各位小伙伴点赞➕收藏⭐➕评论支持杰森呀✌️ 文章目录概述...👲👲作者主页:🔗杰森的博客
📒📒本文摘要:TCP 三次握手,四次挥手知识点精析。备考、面试前看两眼,加深记忆,祝你一臂之力。顺利通过考试、拿到 offer。
💖💖如果本文帮助到你的话,还请各位小伙伴👍点赞➕收藏⭐➕评论💭支持杰森呀✌️
📚概述
“什么是三次握手,四次挥手?”,该问题作为计算机网络学科中常见问题之一,无论是面试还是考研,我们都有必要细细参透其中的奥妙
在学习之前,我们首先需要了解一些基本的概念
📚基础理论
📐传输控制协议
传输控制协议(Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议,在 OSI 模型中完成传输层指定功能。
TCP 使用校验和函数检验数据是否出现错误,在数据发送和接收时均需要计算校验和。✒️TCP 特点
1.TCP 是面向连接的传输层协议
应用程序在使用 TCP 协议前,必须首先完成 TCP 连接的建立。在数据传输结束后,必须释放先前已建立的 TCP 连接
2.每一条 TCP 连接只能有两个端点
TCP 连接只能是点对点,一对一的
3.TCP 提供可靠交付服务
通过 TCP 连接传送的数据,无差错、不丢失、不重复,且按序到达
4.TCP 提供全双工通信
TCP 允许通信双方的应用进程在任何时候都可以发送数据,TCP连接的两端都设有发送、接收缓存,用于临时存放双向通信的数据,上层应用进程在时机恰当时会读取缓存中的数据
5.TCP 面向字节流
图 1 TCP 面向字节流示意图 流是指:流入到进程或从进程流出的字节序列
TCP 把应用程序回传的数据看做一连串的无结构的字节流,不保证接收方应用程序所收到的数据块和发送方应用程序所发出的数据块具有对应大小的关系
接收方应用程序收到的字节流必须和发送方应用程序发出的字节流完全一致,且接收方的应用程序必须具有识别接收字节流,并将其还原为有意义的应用层数据的能力✒️TCP 报文首部
这里需要了解 TCP 报文首部的格式,相关控制位非常重要
图 2 TCP 报文首部的格式示意图 由于 TCP 报文段首部的前 20 个字节是固定的,其后 4n 个字节是根据需要增加的选项,所以 TCP首部的最小长度是 20 字节
1.源端口和目的端口
各占 2 字节,分别写入源端口号、目的端口号
2.序号字段
占 4 字节,范围为
[0,2 ^ 32-1]
,序号使用mod2^32
运算,在一个TCP连接中传送的字节流中的每一个字节都按顺序编号。整个要传送的字节流的起始序号必须在连接建立时设置,首部中的序号字段值则指的是本报文段所发送的数据的第一个字节的序号3.确认号字段
占4字节,是期望收到对方下一个报文段的第一个数据字节的序号。若确认号等于 N,则表明:到序号 N-1 为止数据均己正确接收
4.数据偏移字段
占 4 位,指出 TCP 报文段的数据起始处和 TCP 报文段的起始处的距离。此字段实际上指出了 TCP 报文段的首部长度
5.保留字段
占 6 位,保留为今后使用,目前应置为0
6.紧急 URG
URG=1时,表明紧急指针字段有效,它告诉系统此报文段中有紧急数据,应尽快传送,即提高数据传送的优先级
7.确认 ACK
仅当 ACK=1 时确认号字段才有效,TCP 规定,在连接建立后所有传送的报文段必须将 ACK 置为 1
8.推送 PSH
接收 TCP 收到 PSH=1 的报文段后,将尽快交付接收的应用进程,不再等到缓存都填满后再继续向上交付
9.复位 RST
当 RST=1 时,表明 TCP 连接中出现严重差错,必须释放连接,然后再重新建立传输连接。也可以用于拒绝一个非法的报文段或拒绝打开一个连接
10.同步 SYN
连接建立时用来同步序号,SYN=1就表示这是一个连接请求或连接接受报文
11.终止 FIN
用于释放一个连接,当 FIN=1 时,表明此报文段的发送方的数据己发送完毕,并要求释放传输连接
12.窗口字段
占 2 字节,窗口值范围为
[0,2^16-1]
之间的整数。窗口是指发送本报文段的一方的接收窗口,窗口值作为接收方让发送方设置其发送窗口的依据13.检验和字段
占 2 字,检验和字段检验的范围包括首部和数据两部分
14.紧急指针
占 2 字节,仅当 URG=1 时才有意义,含义是:本报文段中的紧急数据的字数,紧急指针指出了紧急数据的末尾在报文段中的位置
当所有紧急数据都处理完时,TCP就告诉应用程序恢复到正常操作。注意:即使窗口为零时也可发送紧急数据15.选项字段
长度可变,最长可达 40 字节。未使用“选项”时,TCP 首部长度为 20 字节
📚TCP 连接的建立与释放
📐三次握手
TCP
建立连接的过程称为握手,握手需要在客户端和服务器之间交换三个TCP
报文段我们举一个简单的例子帮助大家理解这个问题:试想下面这个场景
你出门在外没带钥匙,而房屋钥匙又仅有一把,在不考虑钥匙丢失在哪里的情况下,今晚你还会回家吗?
虽然此例子并不那么恰当,但是可以类比到三次握手的原因上。如果客户端和服务端有一方出现了问题,那么它们之间的通讯、资源传输必定会出问题
因此,
TCP
三次握手的作用就是使客户端和服务端双方都明确自己的责任,保证双方都具有资源接收和发送的能力图 3 TCP 三次握手示意图 字符释意:
ACK
:确认报文段ack
:确认号SYN
:发送连接请求 / 接收报文段`seq
:发送数据的第一个字节的序号
客户端与服务端资源收发的三次握手过程如下:
*注:图例中的
Ss
、Sa
分别表示Server send
、Server accept
(服务端发送能力、服务端接收能力);Cs
、Ca
分别表示Client send
、Client accept
(客户端发送能力、客户端接收能力)1.第一次握手
第一次握手由客户端发送资源包给到服务端,若该过程正常,则得出结论:服务端接收、客户端发送服务正常
图 4 TCP 建立连接第一次握手示意图 2.第二次握手
第二次握手由服务端发送资源包给到客户端,若该过程正常,则得出结论:服务端发送、客户端接收服务正常
图 5 TCP 建立连接第二次握手示意图 3.第三次握手
这里大家可能就会有疑问了?为什么还需要进行第三次握手呢?前两次不是已经得出结论客户端、服务端接收、发送资源包能力正常了吗?
其实并不是,第一、二次握手只是在单独的过程中得出服务正常的结论,但是在第二次握手结束后,服务端的接收能力和客户端的发送能力未知,这时候便有了
TCP
的第三次握手过程第三次握手由客户端发送资源包给到服务端,若该过程正常,则得出结论:服务端接收、客户端发送服务正常
图 6 TCP 建立连接第三次握手示意图 通过这三次的握手过程我们可以分析得到:第二次是对第一次握手的补充,第三次是对第二次握手的补充,最终正好形成闭环,客户端和服务端都确认了自己的接收、发送能力正常,之后方可进行通信
并且,要完成两者状态的监测,这之间至少需要三次过程,两次并不足以判断自身的服务状态。每一个步骤都相互关联,下一次握手的“响应”由上一次“请求“触发,每次握手得出的结论都是对上一次结果的补充,从而得出最终结果
三次握手过程中,客户端和服务端交换 Initial Sequence Number (
ISN
),为了使对方清除下一步接收到的数据信息应以何序列号进行数据整合并且,ISN 在此过程中是动态生成的。假如 ISN 固定不变,入侵者非常容易就能得出后续数据的确认号,这将会危机到数据信息的安全
📐四次挥手
当成功建立一个
TCP
连接, 服务端在LISTEN
状态下,收到建立连接请求的SYN
报文后,将ACK
和SYN
存放到同一个报文中一起发送给客户端而关闭连接时,服务端收到客户端的
FIN
报文时,仅表示对方不再发送数据,但仍然能够接收数据。此时,服务端不一定将全部数据都发送给了客户端因此服务端关闭有两种方式:
- 立即关闭
- 继续发送一些数据给客户端后,再发送
FIN
报文给客户端(表示同意关闭连接),是否立刻关闭发送数据通道,需交由上层应用决定
所以,客户端的
ACK
和FIN
一般都会分开发送,这里就会导致次数增加一数据传输完毕后,双方均可释放连接。起初,客户端和服务端均处于
ESTABLISHED
状态,然后是客户端主动关闭,服务器被动关闭整个过程请参考下图:
图 7 TCP 释放连接四次挥手示意图 字符释意:
FIN
:连接终止位seq
:发送的第一个字节的序号ACK
:确认报文段ack
:确认号
四次挥手过程:
-
客户端发送第一次挥手,之后由
ESTABLISHED
状态转为FIN_WAIT1
状态 -
服务器收到客户端的第一次挥手之后,发送第二次挥手给服务器,服务器进入
CLOSE_WAIT
状态,等待服务器自身的SOCKET
关闭等处理 -
客户端收到服务器的第二次挥手,进入
FIN_WAIT2
状态,等待服务器关闭 -
服务器发送第三次挥手,然后进入
LAST_ACK
状态 -
客户端收到第三次挥手,发送第四次挥手,客户端进入
TIME_WAIT
状态; -
服务器收到第四次挥手,进入
CLOSED
状态,客户端等待 2MSL 后,进入CLOSED
状态
TCP 状态转换过程见下图:
图 8 TCP 状态转换过程示意图 📚总结
TCP
建立连接的三次握手是指发送了三个报文段,而TCP
断开连接进行四次挥手是指发送了四个报文段,在此过程中,SYN
和FIN
均利用重传进行可靠传输连接的释放本质上两次就可以完成,但若想要完全释放,则需要四次挥手,请看下图
图 9 TCP 连接释放举例 打电话即将结束时,路人甲说完信息“OK,我没事了”后,路人乙回复到“嗯,知道啦”。这是就是完成了 TCP 四次挥手的前两次过程;路人乙马上要挂断电话时,路人甲又忽然想起来某件事,说了很多。这时路人乙又回复到“好的好的”。至此,TCP 四次挥手的后两次过程完毕
💯冲啊!祝各位小伙伴都能拿到大厂 Offer ,成功上岸💯 -
TCP三次握手,四次挥手的全过程,为什么需要三次握手,四次挥手
2022-02-21 11:20:00文章目录TCP介绍三次握手四次挥手滑动窗口拥塞避免算法 TCP介绍 三次握手 四次挥手前言
主要介绍为什么TCP协议需要三次握手和四次挥手
TCP协议的介绍
传输控制协议(TCP,Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议.
- 面向连接(可靠传输)
- 确认,流量、差错控制、定时
- 可靠按序交付
- 不支持多播和广播,开销大
- TCP连接是基于字节流的
- 传输的数据单位是TCP报文段
三次握手
TCP连接的建立:三次握手
- 使每一方确认对方的存在
- 允许双方进行参数的协商
- 进行资源的分配
标志位:
- SYN: Synchronize Sequence Numbers,同步序列编号
- ACK: Acknowledge Character,确认字符 (不同与ack)
关键字: - seq:Sequence Number,序列号 代表本条消息的序列号 (按序交付)
- ack:期待下一次收到的序列号,一般为seq+1
三次握手流程:
- A 的 TCP 向 B 发送 连接请求报文段,其首部中的同步位 SYN = 1 ,并随机选择一个序号 seq = x ,表明传送数据时的第一个数据字节序号为 x。
TCP 协议规定,SYN 置 1 的报文段不能携带数据,但是要消耗一个序号
- B 的 TCP 收到连接请求报文段后,如果同意,则发挥连接同意报文
B 在连接同意报文段中应使 SYN = 1 ,使 ACK = 1 其确认号ack = x + 1 ,自己随机选择一个序号seq = y
3. A 收到此报文后向 B 给出确认,其 ACK = 1 ,确认号 ack = y + 1,seq = x + 1
A 的TCP通知上层应用进程,连接已经建立
4. B 的 TCP 收到主机A的确认后,也通知其上层应用进程:TCP连接已经建立TCP 为什么需要三次握手?而不是两次?
不是两次的主要原因使为了防止多次连接导致连接混乱。 比如A
主机的网络较差,连续发送了多个连接请求,B收到请求后给予想用,但是B不知道A是否收到了同意连接请求,就只能重复同意,这些过期的请求可能回导致网络的混乱
所以设计成三次握手的情况,客户端在接收到服务端SEQ+1的返回消息之后,就会知道这个连接是历史连接,所以会发送报文给服务端,告诉服务端。
所以三次握手的原因就是避免多次建立重复连接那可不可以是四次,五次或者更多次?
可以,但是没有必要,三次已经足够适应需求了,多次的握手可能导致了资源的浪费
四次挥手
TCP连接的释放:双向释放(4次挥手)
首先解释为什么需要四次挥手?
TCP是基于全双工通信的,所以双方都可以主动释放连接。
四次挥手的意义就在于,当 A 发送完最后一条数据之后,但可能B还有未发送给A 的数据。
所以A在发送完收据后可以请求释放连接,此时B给与A响应,告诉A我知道你想断开连接,此时A还可以继续接收B发送的信息。
在B处理完工作后,也请求释放连接。A同意后,就断开连接。
这样可以保证数据正常可靠的交互。四次挥手流程:
FIN : 标志位,请求关闭连接
TCP 的标准规定,FIN报文即使不携带数据信息,也需要消耗一个seq
- 数据传输结束后,通信双方都可以释放连接
现在假设A向B已经发送完数据,A就可以发出连接释放报文段,并停止在发送数据,主动关闭TCP连接
A 把连接释放报文首部的 FIN = 1,其序列号 seq = u,等待 B 的确认。 u 为 A 已传送数据的最后一个字节的序号加1
2. B收到后。发出确认,意思我收到了,ACK = 1,确认号 ack = u+1,而这个报文段自己的序号为seq = v
从A 到 B 这个方向的连接就释放了,TCP 连接处于半关闭状态。B 若发送数据,A仍需要接收- 当B发送完数据后,就可以释放连接。
B 发出的连接释放报文 的== FIN = 1== ,序号为w,ack仍为u+1
- A 收到连接释放报文后,必须发出确认。ACK = 1 ,确认好 ack = w +1,序号seq = u+1。
至此,双方断开连接
-
TCP 三次握手和四次挥手
2022-04-13 23:42:13讲解 TCP 三次握手和四次握手之前,我们先了解一下 TCP 和 UDP 这两个重量级的传输层协议。 用户数据报协议 UDP(User Datagram Protocol): UDP 在传送数据之前不需要先建立连接,远程主机在收到 UDP 报文后,... -
三次握手和四次挥手知识总结(超详细)
2022-04-11 21:46:38利用一把王者荣耀的时间来弄懂三次握手四次挥手这些知识(含生活中的案例,超详细!) -
TCP原理和三次握手和四次挥手过程
2021-08-25 18:51:31TCP原理和三次握手和四次挥手过程TCP三次握手和四次挥手过程TCP是什么?有什么作用?三次握手连接建立详细过程四次挥手连接终止参考 TCP三次握手和四次挥手过程 TCP是什么?有什么作用? TCP 传输控制协议(TCP,... -
一文搞懂TCP的三次握手和四次挥手
2020-08-29 12:20:03一文搞懂TCP的三次握手和四次挥手 -
TCP 核心问题剖析之 “四次挥手”
2022-04-17 15:41:56本文从将从这里开始 照例 本文将带你学会 什么是 TCP 四次挥手 断开连接,我只想挥手三次,你凭什么让我挥手四次? 二次挥手 ACK 对方跑路了咋办? CLOSE_WAIT 在等啥? TIME_WATI 2MSL 等待两个最大报文存活时长... -
TCP的三次握手与四次挥手理解及面试题(很全面)
2018-07-17 20:56:17四次挥手过程理解 1)客户端进程发出连接释放报文,并且停止发送数据。释放数据报文首部,FIN=1,其序列号为seq=u(等于前面已经传送过来的数据的最后一个字节的序号加1),此时,客户端进入FIN-WAIT-1... -
TCP的四次挥手过程
2022-04-25 12:42:29TCP的四次挥手过程 客户端和服务端都可以主动释放连接 这里以客户端示例 情景一:还有数据存在(四次挥手) 客户端发送FIN标识到服务端,告知服务端我要释放连接 服务端收到FIN标识,知道了客户端想断开连接,... -
TCP三次握手和四次挥手的全过程
2022-02-09 20:18:43TCP三次握手和四次挥手的全过程 TCP是主机对主机层的传输控制协议,提供可靠的连接服务,采用三次握手确认建立一个连接: 位码即tcp标志位,有6种表示: SYN(synchronous建立连接) ACK(acknowledgement 表示... -
通俗易懂理解TCP协议三次握手和四次挥手及其常见问题
2021-08-04 22:07:14TCP协议三次握手和四次挥手形象比喻三次握手四次挥手 形象比喻 三次握手:将小明当作客户端,小红当作服务器端,两人写信告白: **第一次握手:**小明告诉小红:我喜欢你。 **第二次握手:**小红告诉小明:我知道了... -
TCP 协议(包含三次握手,四次挥手)
2022-01-04 18:08:48四次挥手挥了一半了,当前可能剩下的两次不挥了(接收方没调用 close 方法,就会导致四次挥手只挥两次,从而没有正确关闭连接) TIME_WAIT: 谁主动断开连接,谁进入 TIME-WAIT 状态,此时该主机已经完成了四次挥手的... -
TCP 四次挥手的过程
2022-01-12 15:19:581、四次挥手的过程 1、刚开始双方处于ESTABLISHED状态。 2、客户端要断开了,向服务器发送FIN报文,在 TCP 报文中的位置如下图: 发送后客户端变成了FIN-WAIT-1状态。注意, 这时候客户端同时也变成了half-... -
TCP四次挥手详解
2021-11-13 17:12:07TCP四次挥手过程和状态变迁 在断开连接之前客户端和服务器都处于ESTABLISHED状态,双方都可以主动断开连接,以客户端主动断开连接为优。 第一次挥手:客户端打算断开连接,向服务器发送FIN报文(FIN标记位被设置... -
详解三次握手和四次挥手
2021-05-24 23:04:01三次握手和四次挥手是各个公司常见的考点,也具有一定的水平区分度,也被一些面试官作为热身题。很多小伙伴说这个问题刚开始回答的挺好,但是后面越回答越冒冷汗,最后就歇菜了。 见过比较典型的面试场景是这样的: ... -
TCP四次挥手
2022-04-26 16:44:46第一次挥手: 主动断开方(客户端,服务的都可以)向对方发送一个FIN结束请求报文,并设置序列号和确认号,随后主动断开方进入FIN_WAIT1状态,这表示主动断开方已经没有业务数据要发给对方了,准备关闭SOCKET连接了... -
TCP的四次挥手(Four-Way Wavehand)
2020-10-17 23:55:15但是,我们却不常听见“四次挥手”,就算听过也未必能详细地说明白它的具体过程。下面就为大家详尽,直观,完整地介绍“四次挥手”的过程。 2、“四次挥手”的详解 所谓的四次挥手即TCP连接的释放(解除)。连接的释放...