计算机网络(2) - TCP协议三次握手四次挥手

2019/01/18

TCP协议三次握手四次挥手

该文档涵盖了参考模型传输层的TCP协议知识点。

阅读完该文档后,您将会了解到:

  • TCP协议中的三次握手
  • TCP协议中的四次挥手
  • TCP协议的常见面试问题

错误之处还望指正。

重点面试内容: 发送的内容和状态(syn/ack/fin/seq) 头条面试遇到过

位码即tcp标志位,有6种标示:

  • SYN(synchronous 开始同步)
  • ACK(acknowledgement 确认)
  • FIN(finish结束)
  • Sequence number(序列号)
  • Acknowledge number(确认号)
  • PSH(push传送)
  • RST(reset重置)
  • URG(urgent紧急)

TCP协议中的三次握手

tcp_connect

如图:

主要有两个标志位: SYN是否请求连接/同步 和 ACK确认收到请求

              序列号的用途是标识特定某一次连接;
  1. 第一次握手:客户端发送 SYN(是否请求连接;1是) 和 seq(序列号,标识特定的本次连接J) 到服务器,客户端进入SYN_SEND状态,等待服务器确认;
  2. 第二次握手:服务器收到连接请求,确认ACK标志位是1,即客户端发起了请求; 服务器发送__ACK(是否收到请求;1是) 和 ack(J+1,特定某次请求); 同步客户端SYN(是否请求连接;1是)和seq(序列号,标识特定的本次连接K)__,此时服务器进入SYN_RECV状态;
  3. 第三次握手:客户端收到服务器的连接请求,向服务器发送__ACK(是否收到请求;1是) 和 ack(K+1,特定某次请求)__,此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。
次数 客户端状态 服务器状态 发送数据
第一次握手 SYN_SEND   SYN:标志位1; seq:序列号,随机数J
第二次握手 established SYN_REVC 标志位SYN和ACK: 1; ack:确认号,J+1; seq:序列号,随机数K
第三次握手 established established 标志位ACK: 1; ack:确认号,K+1
我的理解:

1、状态变换:
  syn(同步), syn_send / syn_recv  英语单词很容易理解;

  • 为什么要三次握手

书: 为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误

说白了就是:防止了服务器端的一直等待而浪费资源

SYN攻击

面试一句话: 在半连接状态下,客户端发送大量不存在ip给服务器,造成正常的SYN丢弃。

在三次握手过程中,服务器发送SYN-ACK之后,收到客户端的ACK之前的TCP连接称为半连接(half-open connect).

此时服务器处于Syn_RECV状态.当收到ACK后,服务器转入ESTABLISHED状态.

Syn攻击就是 客户端在短时间内伪造大量不存在的IP地址,向服务器不断地发送syn包,服务器回复确认包,并等待客户的确认,

由于源地址是不存在的,服务器需要不断的重发直至超时,这些伪造的SYN包将长时间占用未连接队列,正常的SYN请求被丢弃,目标系统运行缓慢,严重者引起网络堵塞甚至系统瘫痪。

Syn攻击是一个典型的DDOS攻击。

检测SYN攻击非常的方便,当你在服务器上看到大量的半连接状态时,特别是源IP地址是随机的,基本上可以断定这是一次SYN攻击.在Linux下可以如下命令检测是否被Syn攻击

netstat -nap grep SYN_RECV
netstat -n -p TCP grep SYN_RECV

一般较新的TCP/IP协议栈都对这一过程进行修正来防范Syn攻击,修改tcp协议实现。主要方法有SynAttackProtect保护机制、SYN cookies技术、增加最大半连接和缩短超时时间等. 但是不能完全防范syn攻击。

TCP协议中的四次挥手

注意:中断连接端可以是Client端,也可以是Server端,那么就是图上的流程反过来操作

tcp_close

解释(以客户端发起断开为例子)

如图:

主要有两个标志位: FIN是否已完成数据传送 和 ACK确认收到请求

              序列号的用途是标识特定某一次连接;
  1. 第一次握手:客户端发送 FIN(是否已完成数据传送;1是) 和 seq(序列号,标识特定的本次连接u) 到服务器,客户端进入FIN_WAIT_1状态,等待服务器确认;
  2. 第二次握手:服务器收到连接请求,确认FIN标志位是1,即客户端发起了断开请求; 服务器发送__ACK(是否收到请求;1是) 和 ack(u+1,特定某次请求); seq(序列号,标识特定的本次连接v)__,客户端等待服务器处理数据,进入FIN_WAIT_2状态;
  3. 第三次握手:服务器传送完数据,向客户端发送__ACK(是否收到请求;1是) 和 ack(u+1,特定某次请求); FIN(是否已完成数据传送;1是) 和 seq(序列号,标识特定的本次连接w)__,此时服务器进入CLOSE_WAIT状态。
  4. 第四次握手:客户端收到服务器的断开请求,向服务器发送__ACK(是否收到请求;1是) 和 ack(w+1,特定某次请求); seq(序列号,标识特定的本次连接u+1)__,Client端等待了2MSL后依然没有收到回复,则证明Server端已正常关闭。
次数 客户端状态 服务器状态 发送数据
第一次握手 FIN_WAIT_1   FIN:标志位1; seq:序列号,随机数u
第二次握手 FIN_WAIT_2   标志位ACK: 1; ack:确认号,u+1; seq:序列号,随机数v
第三次握手   CLOSE_WAIT 标志位ACK: 1; ack:确认号,u+1; 标志位FIN:1; seq:序列号,随机数w
第四次握手 established established 标志位ACK: 1; ack:确认号,w+1; seq:序列号,u+1
总结:
  1、server先关闭,client再关闭
  2、状态:
    FIN : finish
    fin-wait
    close-wait

为什么要四次挥手

那四次挥手又是为何呢?TCP协议是一种面向连接的、可靠的、基于字节流的运输层通信协议。TCP是全双工模式,

这就意味着,当主机1发出FIN报文段时,只是表示主机1已经没有数据要发送了,主机1告诉主机2,它的数据已经全部发送完毕了;

但是,这个时候主机1还是可以接受来自主机2的数据;当主机2返回ACK报文段时,表示它已经知道主机1没有数据发送了,但是主机2还是可以发送数据到主机1的;

当主机2也发送了FIN报文段时,这个时候就表示主机2也没有数据要发送了,就会告诉主机1,我也没有数据要发送了,之后彼此就会愉快的中断这次TCP连接。

完整图

TCP协议的常见面试问题

为什么连接的时候是三次握手,关闭的时候却是四次握手?

答:因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。

但是关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉Client端,“你发的FIN报文我收到了”。只有等到我Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四步握手。

为什么TIME_WAIT状态需要经过2MSL(最大报文段生存时间)才能返回到CLOSE状态?

答:虽然按道理,四个报文都发送完毕,我们可以直接进入CLOSE状态了,但是我们必须假象网络是不可靠的,有可以最后一个ACK丢失。所以TIME_WAIT状态就是用来重发可能丢失的ACK报文。

TCP 有超时重发机制。


Show Disqus Comments

Post Directory