TCP 状态转换

上图中还没有进行握手的时候状态是关闭的。

三次握手状态的改变:

客户端发起握手。

调用 connect() 函数时状态转化为:SYN_SENT。调用 listen() 函数时状态转换为:LISTEN。ESTABLISHED是被连接的状态。

四次挥手状态的改变:

谁发起挥手都可以。上图是客户端发起的挥手。

客户端调用close()函数时状态转化为:FIN_WAIT_1,接收到请求后服务端状态转换为:CLOSE_WAIT(等待关闭)。第二次挥手客户端状态转化为:FIN_WAIT_2。第三次挥手,服务端状态转化为:LAST_ACK,客户端状态转换为:TIME_WAIT。最后就都变为关闭状态。

上图黑线是特殊的情况,红线是客户端,绿色虚线是服务端。

等待2MSL的原因是保证TCP的可靠性。因为在进行第四次挥手的时候,对方没有收到应答(不能是发送ACK就断开连接,还需确保对方接收到了信息)。所以对方再次发送断开请求,本机应答,对方收到应答。

上图中 TIME_WAIT 定时经过两倍报文段寿命:

1. 2MSL(Maximum Segment Lifetime):
主动断开连接的一方, 最后进入一个 TIME_WAIT状态, 这个状态会持续: 2msl
(1) msl: 官方建议: 2分钟, 实际是30s
当 TCP 连接主动关闭方接收到被动关闭方发送的 FIN 和最终的 ACK 后,连接的主动关闭方
必须 处于TIME_WAIT 状态并持续 2MSL 时间。
这样就能够让 TCP 连接的主动关闭方在它发送的 ACK 丢失的情况下重新发送最终的 ACK。
主动关闭方重新发送的最终 ACK 并不是因为被动关闭方重传了 ACK(它们并不消耗序列号,被动关闭方也不会重传),而是因为被动关闭方重传了它的 FIN。事实上,被动关闭方总是
重传 FIN 直到它收到一个最终的 ACK。
2. 半关闭:
当 TCP 链接中 A 向 B 发送 FIN 请求关闭,另一端 B 回应 ACK 之后(A 端进入 FIN_WAIT_2
状态),并没有立即发送 FIN 给 A,A 方处于半连接状态(半开关),此时 A 可以接收 B 发
送的数据,但是 A 已经不能再向 B 发送数据。
从程序的角度,可以使用 API 来控制实现半连接状态:

cpp 复制代码
#include <sys/socket.h>
int shutdown(int sockfd, int how);
sockfd: 需要关闭的socket的描述符
how: 允许为shutdown操作选择以下几种方式:
    SHUT_RD(0):关闭sockfd上的读功能,此选项将不允许sockfd进行读操作。
                该套接字不再接收数据,任何当前在套接字接受缓冲区的数据将被无声的丢弃掉。
    SHUT_WR(1): 关闭sockfd的写功能,此选项将不允许sockfd进行写操作。进程不能在对此套接字发
出写操作。
    SHUT_RDWR(2):关闭sockfd的读写功能。相当于调用shutdown两次:首先是以SHUT_RD,然后以
SHUT_WR。

使用 close 中止一个连接,但它只是减少描述符的引用计数,并不直接关闭连接,只有当描述符的引用计数为 0 时才关闭连接。shutdown 不考虑描述符的引用计数,直接关闭描述符。也可选择中止一个方向的连接,只中止读或只中止写。
注意:
1. 如果有多个进程共享一个套接字,close 每被调用一次,计数减 1 ,直到计数为 0 时,也就是所用进程都调用了 close,套接字将被释放。
2. 在多进程中如果一个进程调用了 shutdown(sfd, SHUT_RDWR) 后,其它的进程将无法进行通信。但如果一个进程 close(sfd) 将不会影响到其它进程。

相关推荐
SendTomo9 分钟前
跨设备文件互传新方案
javascript·网络·webrtc·html5·p2p
啦啦啦啦啦zzzz23 分钟前
moduo网络库 Acceptor TcpConnection
服务器·网络·c++·reactor·网络库
星卯教育tony32 分钟前
NOI Linux 2.0 服务器多用户网页桌面部署方案(腾讯云轻量Ubuntu20.04专属版 CSP复赛比赛环境搭建免安装虚拟机 )
linux·服务器·腾讯云
2601_953988071 小时前
Ricon组态系统vs传统组态软件:为什么选择新一代Web组态平台
前端·后端·物联网·tcp/ip·数学建模·前端框架
Forever Nore1 小时前
LeetCode 14 最长公共前缀 - 纵向扫描
linux·服务器·leetcode
Shadow(⊙o⊙)2 小时前
Linux网络部分——TCP协议服务端客户端交互接口,入门级硬核解析1.0
linux·网络·tcp/ip
小新讲网安2 小时前
HTTP请求走私攻击实战:CL.TE与TE.CL绕过前端服务器全解析
服务器·前端·网络·web安全·http·架构·漏洞
我是谁??13 小时前
Ubuntu22.04更换清华源
linux·运维·服务器
上海安当技术13 小时前
固件签名与Secure Boot:安当CAS如何构建汽车固件信任链
网络·汽车·信任链·boot·secure·固件签名·安当cas
圣殿骑士-Khtangc13 小时前
Go字符串高效拼接性能对比与底层原理分析
服务器·前端·golang