TCP三次握手与四次挥手详解

TCP三次握手与四次挥手详解

@(TCP/IP)服务器

1.TCP报文格式

TCP(Transmission Control Protocol) 传输控制协议。TCP是主机对主机层的传输控制协议,提供可靠的链接服务,采用三次握手确认创建一个链接。cookie

咱们须要知道TCP在网络OSI的七层模型中的第四层(Transport层),IP在第三层(Network层),第二层(Data Link层),在第二层上的数据,咱们叫Frame,在第三层上的数据叫Packet,第四层的数据叫Segment。网络

TCP传输控制协议是面向链接的可靠的传输层协议,在进行数据传输以前,须要在传输数据的两端(客户端和服务器端)建立一个链接,这个链接由一对插口地址惟一标识,便是在IP报文首部的源IP地址、目的IP地址,以及TCP数据报首部的源端口地址和目的端口地址
tcp

上图中有几个字段须要重点介绍下:工具

(1)Sequence Number序号:Seq序号,占32位,用来标识从TCP源端向目的端发送的字节流,发起方发送数据时对此进行标记。是包的序号,用来解决网络包乱序(reordering)问题。.net

(2)Acknowledgement Number确认序号:Ack序号,占32位,只有ACK标志位为1时,确认序号字段才有效,Ack=Seq+1。3d

(3)标志位:共6个,即URG、ACK、PSH、RST、SYN、FIN等,具体含义以下:unix

a. URG(urgent紧急):紧急指针(urgent pointer)有效。指针

b.ACK(acknowledgement 确认):确认序号有效。

c.PSH(push传送):接收方应该尽快将这个报文交给应用层。

d.RST(reset重置):重置链接。

e.SYN (synchronous创建联机):发起一个新链接。

f.FIN(finish结束):释放一个链接。

须要注意的是:

(A)不要将确认序号Ack与标志位中的ACK搞混了。

(B)确认方Ack=发起方Seq+1,两端配对。

2.TCP三次握手

TCP是主机对主机层的传输控制协议,提供可靠的链接服务,采用三次握手确认创建一个链接。
所谓三次握手(Three-Way Handshake)即创建TCP链接,是指创建一个TCP链接时,须要客户端和服务端总共发送3个包以确认链接的创建。
使用wireshark抓包工具分析以下:

能够得出下图:

解释以下:
第一次握手:Client将标志位SYN置为1,随机产生一个值seq=x,并将该数据包发送给Server,Client进入SYN_SENT状态,等待Server确认。

第二次握手:Server收到数据包后由标志位SYN=1知道Client请求创建链接,Server将标志位SYN和ACK都置为1,ack (number )=x+1,随机产生一个值seq=y,并将该数据包发送给Client以确认链接请求,Server进入SYN_RCVD状态。

第三次握手:Client收到确认后,检查ack是否为y+1,标志位ACK是否为1,若是正确则将标志位ACK置为1,ack=y+1,并将该数据包发送给Server,Server检查ack是否为y+1,ACK是否为1,若是正确则链接创建成功,Client和Server进入ESTABLISHED状态,完成三次握手,随后Client与Server之间能够开始传输数据了。

3.TCP四次挥手

所谓四次挥手(Four-Way Wavehand)即终止TCP链接,就是指断开一个TCP链接时,须要客户端和服务端总共发送4个包以确认链接的断开。

链接双方在完成数据传输以后就须要断开链接。因为TCP链接是属于全双工的,即链接双方能够在一条TCP链接上互相传输数据,所以在断开时存在一个半关闭状态,即有有一方失去发送数据的能力,却还能接收数据。所以,断开链接须要分为四次
使用wireshark抓包工具分析以下:

流程以下:

因为TCP链接时全双工的,所以,每一个方向都必需要单独进行关闭,这一原则是当一方完成数据发送任务后,发送一个FIN来终止这一方向的链接,收到一个FIN只是意味着这一方向上没有数据流动了,即不会再收到数据了,可是在这个TCP链接上仍然可以发送数据,直到这一方向也发送了FIN。首先进行关闭的一方将执行主动关闭,而另外一方则执行被动关闭。

第一次挥手:Client将标志位FIN和ACK置为1而且发送发送一个FIN和ACK,用来关闭Client到Server的数据传送,Client进入FIN_WAIT_1状态。

第二次挥手:Server收到FIN后,发送一个ACK给Client,确认序号Ack为收到Seq+1(与SYN相同,一个FIN占用一个序号),序号Seq=1,Server进入CLOSE_WAIT状态。

第三次挥手:Server发送一个FIN,标志位FIN和ACK置为1,用来关闭Server到Client的数据传送,Seq=y,Ack=上次的Seq+1,Server进入LAST_ACK状态。

第四次挥手:Client收到FIN后,Client进入TIME_WAIT状态,接着发送一个ACK给Server,确认序号Ack为收到序号Seq+1,Server进入CLOSED状态,完成四次挥手。

4.为何创建链接须要三次握手?

TCP是主机对主机层的传输控制协议,提供可靠的链接服务,采用三次握手确认创建一个链接。确保数据可以完整传输。
这是由于服务端的LISTEN状态下的SOCKET当收到SYN报文的建连请求后,它能够把ACK和SYN(ACK起应答做用,而SYN起同步做用)放在一个报文里来发
送。

5.为何断开链接须要四次挥手?

当被动方收到主动方的FIN报文通知时,它仅仅表示主动方没有数据再发送给被动方了。
但未必被动方全部的数据都完整的发送给了主动方,因此被动方不会立刻关闭SOCKET,它可能还须要发送一些数据给主动方后,再发送FIN报文给主动方,告诉主动方赞成关闭链接,因此这里的ACK报文和FIN报文多数状况下都是分开发送的。

6.为何TIME_WAIT状态还须要等2MSL后才能返回到CLOSED状态?

这是由于虽然双方都赞成关闭链接了,并且握手的4个报文也都协调和发送完毕,按理能够直接回到CLOSED状态(就比如从SYN_SEND状态到ESTABLISH状态那样);可是由于咱们必需要假想网络是不可靠的,你没法保证你最后发送的ACK报文会必定被对方收到,所以对方处于LAST_ACK状态下的SOCKET可能会由于超时未收到ACK报文,而重发FIN报文,因此这个TIME_WAIT状态的做用就是用来重发可能丢失的ACK报文。

7.SYN攻击原理

在三次握手过程当中,Server发送SYN-ACK以后,收到Client的ACK以前的TCP链接称为半链接(half-open connect),此时Server处于SYN_RCVD状态,当收到ACK后,Server转入ESTABLISHED状态。

SYN攻击就是Client在短期内伪造大量不存在的IP地址,并向Server不断地发送SYN包,Server回复确认包,并等待Client的确认,因为源地址是不存在的,所以,Server须要不断重发直至超时,这些伪造的SYN包将长时间占用未链接队列,致使正常的SYN请求由于队列满而被丢弃,从而引发网络堵塞甚至系统瘫痪。

SYN攻击时一种典型的DDOS攻击,检测SYN攻击的方式很是简单,即当Server上有大量半链接状态且源IP地址是随机的,则能够判定遭到SYN攻击了,使用以下命令能够能够查看SYN_RECV状态:

# netstat -nap | grep SYN_RECV

关于建链接时SYN超时:试想一下,若是server端接到了clien发的SYN后回了SYN-ACK后client掉线了,server端没有收到client回来的ACK,那么,这个链接处于一个中间状态,即没成功,也没失败。因而,server端若是在必定时间内没有收到的TCP会重发SYN-ACK。在Linux下,默认重试次数为5次,重试的间隔时间从1s开始每次都翻售,5次的重试时间间隔为1s, 2s, 4s, 8s, 16s,总共31s,第5次发出后还要等32s都知道第5次也超时了,因此,总共须要 1s + 2s + 4s+ 8s+ 16s + 32s = 2^6 -1 = 63s,TCP才会把断开这个链接。

关于SYN Flood攻击:一些恶意的人就为此制造了SYN Flood攻击——给服务器发了一个SYN后,就下线了,因而服务器须要默认等63s才会断开链接,这样,攻击者就能够把服务器的syn链接的队列耗尽,让正常的链接请求不能处理。因而,Linux下给了一个叫tcp_syncookies的参数来应对这个事——当SYN队列满了后,TCP会经过源地址端口、目标地址端口和时间戳打造出一个特别的Sequence Number发回去(又叫cookie),若是是攻击者则不会有响应,若是是正常链接,则会把这个 SYN Cookie发回来,而后服务端能够经过cookie建链接(即便你不在SYN队列中)。请注意,请先千万别用tcp_syncookies来处理正常的大负载的链接的状况。由于,synccookies是妥协版的TCP协议,并不严谨。对于正常的请求,你应该调整三个TCP参数可供你选择,第一个是:tcp_synack_retries 能够用他来减小重试次数;第二个是:tcp_max_syn_backlog,能够增大SYN链接数;第三个是:tcp_abort_on_overflow 处理不过来干脆就直接拒绝链接了。

参考文档

http://blog.csdn.net/hulifangjiayou/article/details/47283387
http://blog.csdn.net/yanxi252515237/article/details/51955675

《TCP那些事儿》云头条做者 陈皓

相关文章
相关标签/搜索