Home TCP三次握手和四次挥手的本质
Post
Cancel

TCP三次握手和四次挥手的本质

三次握手

1
connect(<描述符>,<服务器IP地址和端口号>,...)      

三次握手的本质是确认通信双方收发数据的能力
第一次握手,服务器确认了:客户端的发送能力和服务器的接收能力;
第二次握手,客户端确认了通信双方的收发能力,此时客户端套接字中连接状态改为ESTABLISHED;
第三次握手,服务器也确认了自己的发送能力和客户端的接收能力, 通信双方的收发能力都得到确认;
此时服务器套接字中连接状态改为ESTABLISHED。

四次挥手

断开TCP连接

TIME_WAIT状态也称为2MSL等待状态。
每个具体TCP实现必须选择一个报文段最大生存时间MSL(Maximum Segment Lifetime)
它是任何报文段被丢弃前停留在网络内的最长时间。
因为TCP报文段以IP数据包在网络内传输,而IP数据包则有限制其生存时间的TTL字段。

常见问题

什么是SYN攻击?

服务器端必须收到第三次握手时客户端的ACK报文才能建立连接,所以服务器容易受到SYN洪泛攻击。
SYN攻击就是Client在短时间内伪造大量不存在的IP地址,并向Server不断地发送SYN包,
Server则回复SYN+ACK包,并等待Client第三次握手确认,由于源地址不存在,Server会不断重传直至超时,
这些伪造的SYN包将长时间占用未连接队列,导致正常的SYN请求因为队列满而被丢弃,从而引起网络拥塞甚至系统瘫痪。
SYN攻击是一种典型的DoS/DDoS攻击。
当你在服务器上看到大量的半连接状态的套接字时,特别是源IP地址是随机的,
基本上可以断定这是一次SYN攻击。在Linux/Unix上可以使用系统自带的netstats命令来检测SYN攻击:

1
netstat -n -p TCP | grep SYN_RECV       

如果已经建立了连接,但是客户端突然出现故障了(不发数据了)怎么办?

TCP设有一个保活计时器(keepalive timer),客户端如果出现故障,
服务器不能一直等下去,白白浪费资源。
服务器每收到一次客户端的数据后都会重新复位这个计时器,时间通常是设置为2小时,
若两小时还没有收到客户端的任何数据,服务器就会发送一个探测报文段,以后每隔75秒钟发送一次。
若一连发送10个探测报文仍然没反应,服务器就认为客户端出了故障,接着就关闭连接。

为什么客户端发出第四次挥手的确认报文后要等2MSL的时间才能释放连接?

这里同样是要考虑丢包的问题,如果第四次挥手的报文丢失,
服务端没收到确认ack报文就会重发FIN报文,这样报文一去一回最长时间就是2MSL,
所以需要等这么长时间来确认服务端确实已经收到了。

一些流程图

TCP头部格式

TCP序号和ACK号的交互

TCP整体流程

应用程序委托协议栈收发数据的过程

参考资料

$[1]$ 户根勤. 网络是怎样连接的 人民邮电出版社. [2017-1-1]
$[2]$ James F. Kurose; Keith W. Ross Computer Networking: A Top-Down Approach Pearson. [2012-3-5]

This post is licensed under CC BY 4.0 by the author.

Crash Course Computer Science学习笔记:CPU篇

线性代数第1章:线性方程组