博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
详解TCP的三次握手(建连)四次挥手(断连)
阅读量:4289 次
发布时间:2019-05-27

本文共 1849 字,大约阅读时间需要 6 分钟。

详解三次握手建连

TCP是基于链接的,所以在传输数据前需要先建立链接,TCP在传输上是双工传输,不区分Client端与Server端,为了便于理解,我们把主动发起建连请求的一端称为Client端,把被动建立链接的一端称作Server端。

如下图,建连的时序是从上到下,左右两边的绿字代表Client端与Server端当时的链接状态。

三次握手
首先建立链接前需要Server端先监听端口,因此Server端建立链接前的初始状态就是LISTEN状态,这时Client端准备建立链接,先发送一个SYN同步包,发送完同步包后,Client端的链接状态变成了SYN_SENT 状态。Server端收到SYN后,同意建立链接,会向Client端回复一个ACK。

由于TCP是双工传输,Server端也会同时向Client端发送一个SYN,申请Server向Client方向建立链接。发送完ACK和SYN后,Server端的链接状态就变成了SYN_RCVD。

Client收到Server的ACK后,Client端的链接状态就变成了ESTABLISHED状态,同时Client向Server端发送ACK,回复Server端的SYN请求。

Server端收到Client的ACK后,Server端的链接状态也就变成了ESTABLISHED状态,此时链接完成,双方随时可以进行数据传输。

我们需要明白三次握手是为了建立双向链接,需要记住Client端和Server端的链接状态变化。另外回答建连的问题时,可以提到SYN洪水攻击发生的原因,就是Server端收到Client端的SYN请求后,发送了ACK和SYN,但是Client不进行回复,导致Server端大量的链接处在SYN_RCVD状态,进而影响其他正常请求的建连。可以设置tcp_synack_retries=0加快半链接的回收速度,或者调大tcp_max_syn_backlog来应对SYN洪水攻击。

详解四次挥手断连

再来看看 TCP 的断连,如下图所示。

四次挥手
TCP 链接的关闭,通信双方都可以先发起,我们暂且把先发起的一方看作 Client,从图中看出,通信中 Client 和 Server 两端的链接都是 ESTABLISHED 状态,然后 Client 先主动发起了关闭链接请求,Client 向 Server 发送了一个 FIN 包,表示 Client 端已经没有数据要发送了,然后 Client 进入了 FIN_WAIT_1 状态。

Server 端收到 FIN 后,返回 ACK,然后进入 CLOSE_WAIT 状态。此时 Server 属于半关闭状态,因为此时 Client 向 Server 方向已经不会发送数据了,可是 Server 向 Client 端可能还有数据要发送。

Server 端收到 FIN 后,返回 ACK,然后进入 CLOSE_WAIT 状态。此时 Server 属于半关闭状态,因为此时 Client 向 Server 方向已经不会发送数据了,可是 Server 向 Client 端可能还有数据要发送。

Client 端收到 Server 端的 FIN 后,回复 ACK,然后进入 TIME_WAIT 状态。TIME_WAIT 状态下需要等待 2 倍的最大报文段生存时间,来保证链接的可靠关闭,之后才会进入 CLOSED 关闭状态。而 Server 端收到 ACK 后直接就进入 CLOSED 状态。

为什么需要等待 2 倍最大报文段生存时间之后再关闭链接,原因有两个:

1.保证 TCP 协议的全双工连接能够可靠关闭;
2.保证这次连接的重复数据段从网络中消失,防止端口被重用时可能产生数据混淆。

从这个交互流程可以看出,无论是建连还是断链,都是需要在两个方向上进行,只不过建连时,Server 端的 SYN 和 ACK 合并为一次发送,而断链时,两个方向上数据发送停止的时间可能不同,所以不能合并发送 FIN 和 ACK。这就是建连三次握手而断链需要四次的原因。

另外回答断链的问题时,可以提到实际应用中有可能遇到大量 Socket 处在 TIME_WAIT 或者 CLOSE_WAIT 状态的问题。一般开启 tcp_tw_reuse 和 tcp_tw_recycle 能够加快 TIME-WAIT 的 Sockets 回收;而大量 CLOSE_WAIT 可能是被动关闭的一方存在代码 bug,没有正确关闭链接导致的。

转载地址:http://ekhgi.baihongyu.com/

你可能感兴趣的文章
Crackme3 破解教程
查看>>
奖学金评比系统(数据库系统设计版)
查看>>
HTTP Live Streaming直播
查看>>
rtmp+fms rtmp 视频发布环境
查看>>
最简单的基于librtmp的示例:发布(FLV通过RTMP发布)
查看>>
Windows/Linux下引用jar包,并用javac/java编译运行
查看>>
HttpClient使用详解
查看>>
HttpClient详解(一)
查看>>
httpclient 请求http数据,json转map
查看>>
git 常用命令
查看>>
用递归方法建立二叉树
查看>>
用递归方法对二叉树进行先序、中序和后序遍历
查看>>
翻转二叉树
查看>>
逆序链表
查看>>
epoll 使用详解
查看>>
stl 中 set容器用法
查看>>
有序数组求交集
查看>>
文字常量区与栈
查看>>
非阻塞connect 编写方法
查看>>
epoll 边沿触发
查看>>