了解TCP的三次握手和四次挥手
了解TCP的三次握手和四次挥手
一、 TCP/IP OSI参考模型
了解TCP的三次握手和四次挥手,我们首先从TCP/IP OSI参考模型说起。
OSI(Open System Interconnect),即开放式系统互联。OSI定义了网络互连的七层框架(物理层、数据链路层、网络层、传输层、会话层、表示层、应用层),即ISO开放互连系统参考模型。每一层实现各自的功能和协议,并完成与相邻层的接口通信。如下图。

由图可知,TCP主要位于传输层,TCP是基于字节流的传输层通信协议,将上层[应用层]的数据流分割成报文段进行发送;
二、 三次握手
首先我们要了解为什么要进行三次握手,目的是什么?然后握手的流程是什么样的?以及握手过程中可能出现的问题。
1. “三次握手”的目的:
是为了建立可靠的TCP连接,握手过程中会初始化Seq的初始值,从而保证通信的顺序性,防止因网络问题而乱序;
2. “三次握手”的流程:

图片来自网络
TCP/IP协议中,为了提供可靠的连接,采用三次握手建立一个连接;流程描述如下:
|
第一次握手:建立连接时,A发送SYN包(seq=x)到B,并进入SYN_SEND状态,等待B确认;
第二次握手:B收到SYN包,必须向A返回一个ACK包(ack=x+1)确认,同时自己也发送一个SYN包(syn=y),即SYN+ACK包,并进入SYN_RECV状态;
第三次握手:A收到B的SYN+ACK包,向B发送ACK包(ack=y+1)确认,此包发送完毕,A和B进入established状态; |
由上面流程可知,第一次seq为1,然后下一次返回的ack序号是在对方上一次的seq的基础上加 +1。
在“三次握手”的过程中可能出现风险,具体描述如下:
3. SYN FLOOD攻击:
介绍:SYN Flood是种典型的DoS (拒绝服务) 攻击,效果就是服务器TCP连接资源耗尽,停止响应正常的TCP连接请求。
原因:只进行了第二次握手,而不进行第三次握手,此时服务器没有收到客户端的ACK确认;
后果:服务器会不断重试到超时(5次),linux默认是等待63秒才断开;会把服务器的连接数耗尽,影响到正常请求不能处理;
命令查看及防护:
查看linux网络状态命令:
netstat -anp |awk '{print $6}' |sort|uniq -c |sort -rn
查看是那些ip发出的SYN命令:
netstat -an | grep SYN | awk '{print $5}' | awk -F: '{print $1}' | sort | uniq -c | sort -nr | more
查看linux默认的syn配置:
sysctl -a | grep _syn
>>>#
|
net.ipv4.tcp_max_syn_backlog = 262144 |
//是SYN队列的长度,加大长度可以容纳更多等待连接的网络连接数 |
|
net.ipv4.tcp_syncookies = 1 |
//是否打开SYN Cookie 功能,该功能可以防止部分SYN攻击;默认为0关闭,1开启 |
|
net.ipv4.tcp_synack_retries = 2 |
//SYNACK(第二次握手)的重试连接次数,默认5,建议调小控制重试次数 |
|
net.ipv4.tcp_syn_retries = 2 |
//SYN的重试连接次数,默认5,建议调小控制重试次数 |
总结:针对SYN FLOOD攻击,最快捷的方式就是开启SYN Cookie功能。
三、 四次挥手
我们要了解四次挥手目的是什么?为什么需要四次?然后挥手的流程是什么样的?以及握手过程中可能出现的问题。
1. “四次挥手”的目的
为了终止TCP连接。
2. “四次挥手”的流程:

图片来自网络
四次挥手流程描述如下:
|
第一次挥手:A发送一个FIN(seq=x)包,ACK(ack=y)包{上图中没有注明]用来关闭A到B的数据传送,A进入FIN_WAIT_1状态;
第二次挥手:B收到FIN后,发送一个ACK(ack=x+1)包给A,并进入CLOSE_WAIT状态,同时通知应用程序,对方A要求关闭连接;
第三次挥手:这时B的应用程序通知TCP可以关闭连接,则会发送一个FIN(seq=y,ack=x+1)包,用来关闭B到A的数据传送,B进入LAST_ACK状态;
第四次挥手:A收到FIN后,A进入TIME_WAIN状态,接着返回一个ACK(ack=y+1包)给B,B进入CLOSED状态,完成四次挥手; |
3. 为什么需要“四次挥手”
因为全双工,收发两个方向的连接都可以独立关闭,以避免A数据发送完毕,再向B发送FIN关闭连接,而这时B它的上层[应用层]可能正在处理数据,需要等B的[应用层]数据处理完成后,再向主动A发出第三次挥手。这样就比“三次握手”多一次连接,需要四次挥手。
4. TIME_WAIT状态为什么需要等待2MSL时间?
1) 确保有足够的时间让对方收到ACK包;
2) 避免新旧连接混淆;
具体描述:
第一,假若第四次挥手的ACK报文段丢失,因而使处在LAST-ACK状态的B收不到对方发送的最后一个ACK包。B会超时重传这个FIN+ACK报文段,而A就能在2MSL时间内收到这个重传的FIN+ACK报文段。但如果A在TIME-WAIT状态不等待一段时间,而是在发送完ACK报文段后就立即释放连接,就无法收到B重传的FIN+ACK报文段,因而也不会再发送一次确认报文段。这样,B就无法按照正常的步骤进入CLOSED状态。
第二,A在发送完ACK报文段后,再经过2MSL时间,就可以使本连接持续的时间所产生的所有报文段都从网络中消失。这样就可以使下一个新的连接中不会出现这种旧的连接请求的报文段。
5. 服务器出现大量的CLOSE_WAIT状态的原因?
该问题是我们有时在使用HttpClient时偶尔会遇到的问题。
原因:对方关闭socket连接,我方忙于读和写,没有及时关闭连接(方便理解:可参考“四次挥手”图的第三次挥手,假如对方没有返回ACK会怎么样);
防范:
1) 检查代码,特别是释放资源的代码;
2) 检查配置,特别是处理请求的线程配置;
四、 关于TCP报文头的说明

标识说明:
- 16位源端口号和16位目的端口号:通信双方的端口号,用来标识不同的应用进程。
- 32位序号和32位确认序号:使数据包按顺序处理,保证连接的可靠性;
- 4位首部长度/数据偏移:最大值为1111。因为TCP报头最多60个字节,但[选项]长度不确定,如何定位到[数据]起始位置,可通过该标识定位。
- 6位保留:为将来定义新的用途保留,现在一般置0。
- 6位控制位:0或1:
- URG:紧急指针标志,为1时表示紧急指针有效,为0则忽略紧急指针。
- ACK:确认序号标志,为1时表示确认号有效,为0表示报文中不含确认信息,忽略确认号字段。
- PSH:push标志,为1表示是带有push标志的数据,指示接收方在接收到该报文段以后,应尽快将这个报文段交给应用程序,而不是在缓冲区排队。
- RST:重置连接标志,用于重置由于主机崩溃或其他原因而出现错误的连接。或者用于拒绝非法的报文段和拒绝连接请求。
- SYN:同步序号,用于建立连接过程,在连接请求中,SYN=1和ACK=0表示该数据段没有使用捎带的确认域,而连接应答捎带一个确认,即SYN=1和ACK=1。
- FIN:finish标志,用于释放连接,为1时表示发送方已经没有数据发送了,即关闭本方数据流。
- 16位窗口:滑动窗口大小,用来告知发送端接受端的缓存大小,以此控制发送端发送数据的速率,从而达到流量控制。
- 16位校验和:奇偶校验函数,检验范围包括首部和数据两部分,用来检验传输过程中是否有误,由发送端计算和存储,并由接收端进行验证。
- 选项/填充:常见的可选项是MSS表示本端所能接受的最大报文段的长度,在第一次握手中指明这个字段。为保证选项长度是32的整数倍,所以填充位会加额外的零。
- 数据部分:TCP 报文段中的数据部分是可选的。在一个连接建立和一个连接终止时,双方交换的报文段仅有 TCP 首部。如果一方没有数据要发送,也使用没有任何数据的首部来确认收到的数据。在处理超时的许多情况中,也会发送不带任何数据的报文段。
五、 介绍滑动窗口
1. 滑动窗口:
告诉发送端,接收端缓存的大小,以此控制发送端发送数据的速率,从而达到控制流量;TCP的滑动窗口的单位是字节的;
a. 保证tcp的可靠性;
b. 保证tcp的流量控制(告诉发送端另一端的缓存,防止处理不过来);
2. RTT和RTO概念:
RTT: 发送一个数据包到收到对应的ACK,所花费的时间;
RTO: 重传时间间隔;根据RTT计算出来,当规定时间没有收到ACK,则重传;
3. 计算过程:

- AdvertisedWindow[滑动窗口] = MaxRcvBuffer[最大接收缓存] - (LastByteRcvd - LastByteRead)
- EffectiveWindow[窗口内剩余可发送大小] = AdvertisedWindow - (LastByteSent - LastByteAcked)
4. TCP会话发送四种状态:
#1:已发送并且已收到回应;#2:已发送还没收到回应,#3:没有发送但允许发送;#4:没有发送且不允许发生(由于窗口大小限制);
其中:#2+#3组成为:发送窗口;

5. TCP会话接收四种状态原理同上;
#1:已接收并且已回应;#2:已接收但未回应;#3:没有接收但允许接收;#4:没有发送且不允许接收(由于窗口大小限制);
其中#3为:接收窗口;
六、 抓包工具wireshark
我们通过抓包工具wireshark来加深理解”三次握手”和“四次挥手”
找一个网址http://www.xxxxxx.net/ (ip: xxx.xx.xx.xx)来示范:
1. 握手过程:

2. 挥手过程:


浙公网安备 33010602011771号