参考:网络编程知识预备(2) ——三次握手与四次挥手、流量控制(滑动窗口)、拥塞控制、半连接状态、2MSL_行稳方能走远的博客-CSDN博客
目录
一、三次握手
什么是三次握手?
三次握手图解
三次握手过程解析
(1)第一次握手
(2)第二次握手
(3)第三次握手
二、四次挥手
什么是四次挥手?
四次挥手图解
四次挥手过程解析
(1)第一次挥手
(2)第二次挥手(半连接)
(3)第三次挥手
(4)第四次挥手
三、2MSL作用
四、 常见问题
1、为什么连接是三次握手,关闭却要四次挥手(半连接)?
2、连接中途客户端突然故障怎么办(保活计时器、探测报文段、心跳包)?
一、三次握手
什么是三次握手?
手机能够使用联网功能是因为手机底层实现了 TCP / IP 协议,可以使手机终端通过无线网络建立TCP连接。TCP协议可以对上层网络提供接口,使上层网络数据的传输建立在“无差别”的网络之上。
TCP共有6个标志位,常见的:
| 标志位 | 含义 |
|---|---|
| SYN(synchronous) | 建立连接 |
| ACK(acknowledgement) | 响应确认 |
| FIN(finish) | 结束 |
| RST(reset) | 重置 |
建立起一个TCP连接需要经过“三次握手”
三次握手图解



三次握手过程解析:
(1)第一次握手
客户端发送 SYN 包( syn = j )到服务器,并进入 SYN_SEND 状态,等待服务器确认。
j 是一个随机数,通过看服务器返回的 j + 1 是否正确,判断第一次握手服务器是否正确响应。
(2)第二次握手
服务器确认客户的 SYN 包,同时发送 ACK 包( ack = j + 1 )作为回应;
自己也发送一个 SYN 包( syn = k ),共两个包,此时服务器进入 SYN_RECV 状态;
k 也是一个随机数,也是用于看客户端返回的 k+1 是否正确,判断第二次握手客户端是否正确响应。
(3)第三次握手
客户端收到服务器的 SYN+ACK 包,向服务器发送确认包 ACK ( ack = k + 1 ),此包发送完毕,客户端和服务器进入 ESTABLISHED 状态,完成三次握手。
握手过程中传送的包里不包含数据,三次握手完毕后,客户端与服务器才正式开始传送数据。理想状态下,TCP连接一旦建立,在通信双方中的任何一方主动关闭连接之前,TCP 连接都将被一直保持下去。
二、四次挥手
什么是四次挥手?
四次挥手即终止TCP连接,就是指断开一个TCP连接时,需要客户端和服务端总共发送4个包以确认连接的断开。在 socket 编程中,这一过程由客户端或服务端任一方执行close来触发。
四次挥手图解

四次挥手过程解析:
(1)第一次挥手
客户端发送一个 FIN = M,用来关闭客户端到服务器端的数据传送,客户端进入 FIN_WAIT_1状态 。
意思是说"我客户端没有数据要发给你了",但是如果你服务器端还有数据没有发送完成,则不必急着关闭连接,可以继续发送数据。
(2)第二次挥手(半连接)
服务器端收到 FIN 后,先发送 ack = M + 1,告诉客户端,你的请求我收到了,但是我还没准备好,请继续你等我的消息。这个时候客户端就进入FIN_WAIT_2 状态(半连接状态),继续等待服务器端的FIN报文。
(3)第三次挥手
当服务器端确定数据已发送完成,则向客户端发送 FIN = N 报文,告诉客户端,好了,我这边数据发完了,准备好关闭连接了。服务器端进入LAST_ACK状态。
(4)第四次挥手
客户端收到 FIN = N 报文后,就知道可以关闭连接了。
但是他还是不相信网络,怕服务器端不知道要关闭,所以发送 ack = N + 1后进入TIME_WAIT状态,如果 Server 端没有收到 ACK 则可以重传。服务器端收到ACK后,就知道可以断开连接了。
客户端等待了 2MSL 后依然没有收到回复,则证明服务器端已正常关闭,那好,我客户端也可以关闭连接了。
三、2MSL作用

-
假设客户端最后一个确认报文段丢失,如果没有2MSL等待时间,那么服务端一直发送超时重发报文,最终无法进入CLOSED状态
-
2MSL时长可以使本次连接持续时间内所产生的所有报文段都从网络中消失,这样就可以使下一个新的TCP连接中不会出现旧连接中的报文段
四、 常见问题
1、为什么连接是三次握手,关闭却要四次挥手(半连接)?
建立连接时,ACK 和 SYN 可以放在一个报文里来发送。
而关闭连接时,被动关闭方可能还需要发送一些数据后,再发送 FIN 报文表示同意现在可以关闭连接了,所以它这里的 ACK报文 和 FIN报文 多数情况下都是分开发送的。
说得尽可能具体一些就是
客户端发送FIN关闭报文,但是服务端仍在给他发送数据不能马上停止,服务端先给出ACK报文回应(你的请求我收到了,但要等我发完数据才能关闭哦)。当服务端发送完毕后,再发送FIN报文请求关闭,所以这两个报文不能同时发送,故有了四次挥手。
如果把三次握手改为仅需要两次握手,可能发生死锁。
2、连接中途客户端突然故障怎么办(保活计时器、探测报文段、心跳包)?

TCP还设计有一个①保活计时器,显然,客户端如果出现故障,服务器不能一直等下去,白白浪费资源。
服务器每收到一次客户端的请求后都会重新复位这个计时器,时间通常是设置为2小时,若两小时还没有收到客户端的任何数据,服务器就会发送一个②探测报文段,以后每隔75秒钟发送一次。若一连发送10个探测报文仍然没反应,服务器就认为客户端出了故障,接着就关闭连接。
另外的:如果客户端没有数据发送,又不想断开的话还要发③心跳包,心跳包这个数据没用,只是告诉服务器我客户端还在【长连接】
智能家居项目目录
智能家居(1) —— 工厂模式引入&工厂模式实现继电器控制
智能家居(2) —— 工厂模式实现烟雾报警
智能家居(3) —— 串口通信(语音识别)线程控制
智能家居(4) —— 网络服务器线程控制
智能家居(5) —— 智能家居项目整合(语音控制线程,网络控制线程、烟雾报警线程)
网络编程知识预备(1) —— 7层OSI网络模型
网络编程知识预备(2) —— 三次握手与四次挥手、半连接状态、2MSL
网络编程知识预备(3) —— TCP流量控制(滑动窗口)、拥塞控制
网络编程知识预备(4) —— SOCKET、TCP、HTTP之间的区别与联系
网络编程知识预备(5) —— 了解应用层的HTTP协议与HTTPS协议
网络编程知识预备(6) —— libcurl库简介及其编程访问百度首页
智能家居(6) —— 香橙派摄像头安装实现监控功能
智能家居(7) —— 人脸识别 & 翔云平台编程使用(编译openSSL支持libcurl的https访问、安装SSL依赖库openSSL)
智能家居(8) —— 香橙派摄像头加入设备工厂


















