TCP三次握手与四次挥手
为了更好的理解TCP建立连接与释放连接的过程,我们不妨先了解TCP报文结构。
TCP报文包含 首部 和 数据部分 :
重点认识一下 TCP首部 结构:
1、源端口与目的端口:
各占两个字节,共4个字节。用来告知主机该报文的源与目的。
2、序号(seq number)
由于TCP是面向流的有序可靠连接,在一个TCP连接中传输的字节流中的每个字节都需要按顺序编号。
序号字段指的是本报文段所发送的数据的 第一个字节 的序号。
3、确认号(ack number)
表示 期望收到对方下一个报文段的序号值 ,同时表示前面的序号值都已经 成功接收 ,体现 累积确认机制 。
4、确认ACK
当ACK=1时,确认号有效。
5、同步SYN
当SYN=1时,表明这是一个请求连接报文段。
6、终止FIN
当FIN=1时,表示此报文段的发送方的数据已发送完毕,要求释放TCP连接。
7、 窗口大小(window size)
流量控制 中的滑动窗口大小,根据接收方的接收缓冲区剩余大小设置。
TCP 的整个交流过程可以总结为:建立连接,传输数据,释放连接。
TCP连接的建立采用客户端-服务器模式,我们将主动方成为客户端(Client),被动方成为服务器(Server)。
1、 第一次握手 :Client主动打开连接,发送TCP报文( SYN = 1,seq = i ),进行第一次握手,进入 SYN_SEND 状态;
2、 第二次握手 : Server收到了SYN报文,发送返回报文( ACK = 1,SYN = 1,ack = i+1, seq = j ),进行第二次握手,进入 SYN_RCVD 状态;
3、 第三次握手 : Client收到来自Server的报文,返回ACK报文( ACK = 1, ack = j+1,seq = i+1 ),进行第三次握手,进入 ESTABLISHED 状态; 另外, 第三次握手一般已经可以携带数据了 。
TCP有一个特别的概念叫做 半关闭 ,这个概念是说,TCP连接时全双工的连接,因此在关闭连接的时候,必须关闭传送和接收两个方向上的连接。
1、 第一次挥手 : Client发送关闭连接报文段( FIN= 1, seq = n ),进入 FIN_WAIT_1 状态;
2、 第二次挥手 : Server收到来自Client的FIN之后,立即返回一个 ACK=1 报文段(ack = n+1),进入 CLOSE_WAIT 状态;
此时Server还是可以发送数据给Client。
3、 第三次挥手 : 当Server确定所有数据都发送完毕之后,发送 FIN=1 报文段(seq = m),进入 LAST_ACK 状态;
4、 第四次挥手 : Client收到之后,返回 ACK=1 报文段(ack = m+1),进入 TIME_WAIT 状态;
Client等待2MSL(MSL,最长报文段寿命)之后进入CLOSED状态,Server收到最后一个ACK之后,也进入CLOSED状态。
在三次握手过程中,Server发送第二次握手报文之后,收到Client的ACk之前的状态称为 半连接 状态。在半连接状态的Server会为其认为即将完成连接的Client分配资源。
而SYN Flood攻击就是,在短时间内伪造大量不存在的IP地址,向Server不断发送SYN包,Server为这些伪造的Client分配资源,并返回SYN+ACK报文段,由于IP地址无效,所以Server不会收到第三次握手的ACK,需要不断发送直至超时,这些伪造的Client长时间占用未连接队列与Server预分配的资源,造成Server崩溃,无法响应正常的SYN包。
1、SYN cookies技术:先不分配数据区,而根据SYN计算一个cookies值,当收到Client的ACk之后,再进行对比,分配资源。
2、增大最大半连接和缩短超时时间。
1、TIME_WAIT状态能确保Server正常进入CLOSE状态:
TIME_WAIT状态是在Client发完最后一个ACK之后进入的状态,如果这个ACK丢失,则Server不能确认进入CLOSE状态,超时后,Server会重新发送FIN报文段,此时处于TIME_WAIT状态的Client就能收到FIN,重发ACK,确保四次挥手完成。
2、TIME_WAIT状态有 净空 的效果:
防止已经失效的连接请求出现在下次连接中。经过TIME_WAIT状态,可以使本连接内的所有请求都在网络中消失(从而起到净空的效果,不会赢下下一次连接)。
1、 只有主动close一方才会出现TIME_WAIT状态,只有TCP连接为 短连接 情况下才有可能出现大龄的TIME_WAIT状态。
2、 服务器使用短连接,每次客户端请求后,服务器都会主动发送FIN关闭连接。最后进入TIME_WAIT状态。由此,如果访问量过大的Web Server,会存在大量的TIME_WAIT状态。
可以通过修改内核参数,快速回收TIME_WAIT资源。
3、如果一直存在大量TIME_WAIT状态,回收不及时的话,会占用大量服务器资源,可能造成该无法提供服务的问题。
【参考】
[1] 理解TCP 和 UDP
[2] 《计算机网络》
简述TCP的三次握手过程。
TCP握手协议 :在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接。
1、第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认; SYN:同步序列编号(Synchronize Sequence Numbers)
2、第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;
3、第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。
完成三次握手,客户端与服务器开始传送数据。
所谓的三次握手(three times handshake;three-way handshaking)即对每次发送的数据量是怎样跟踪进行协商使数据段的发送和接收同步,根据所接收到的数据量而确定的数据确认数及数据发送、接收完毕后何时撤消联系,并建立虚连接。
为了提供可靠的传送,TCP在发送新的数据之前,以特定的顺序将数据包的序号,并需要这些包传送给目标机之后的确认消息。TCP总是用来发送大批量的数据。当应用程序在收到数据后要做出确认时也要用到TCP。
简述TCP连接三次握手四次挥手
1.第一次握手:A的TCP客户进程向B发出连接请求报文段(首部的同步位SYN=1,初始序号seq=x,SYN=1的报文段不能携带数据,但要消耗掉一个序号),此时TCP客户进程进入SYN-SENT(同步已发送)状态。
2.第二次握手:B收到连接请求报文段后,如同意建立连接,则向A发送确认报文(SYN=1,ACK=1,确认号ack=x+1,初始序号seq=y),B进程进入SYN-RCVD(同步收到)状态,A进入ESTABLISHED(已建立连接)。
3.第三次握手:A收到B的确认后,要向B发送确认收到确认的报文段(ACK=1,确认号ack=y+1,序号seq=x+1,初始为seq=x,第二个报文段所以要+1),ACK报文段可以携带数据,不携带数据则不消耗序号,TCP连接已经建立,当B收到A的确认后,也进入ESTABLISHED状态。
可以看到,三次握手过程中,A的状态变化为 CLOSED-SYN-SEND-ESTABLISHED。B的状态变化为(CLOSED)LISTEN-SYNC-RECEIVED-ESTABLISHED,两者都经过3次状态变化。
为何需要最后的客户端应答(为什么需要第三次握手)?
一文搞懂TCP的三次握手和四次挥手
TCP的三次握手和四次挥手实质就是TCP通信的连接和断开。
三次握手:为了对每次发送的数据量进行跟踪与协商,确保数据段的发送和接收同步,根据所接收到的数据量而确认数据发送、接收完毕后何时撤消联系,并建立虚连接。
四次挥手:即终止TCP连接,就是指断开一个TCP连接时,需要客户端和服务端总共发送4个包以确认连接的断开。
TCP三次握手、四次挥手时序图
TCP协议位于传输层,作用是提供可靠的字节流服务,为了准确无误地将数据送达目的地,TCP协议采纳三次握手策略。
三次握手原理:
第1次握手:客户端发送一个带有SYN(synchronize)标志的数据包给服务端;
第2次握手:服务端接收成功后,回传一个带有SYN/ACK标志的数据包传递确认信息,表示我收到了;
第3次握手:客户端再回传一个带有ACK标志的数据包,表示我知道了,握手结束。
其中:SYN标志位数置1,表示建立TCP连接;ACK标志表示验证字段。
可通过以下趣味图解理解三次握手:
三次握手过程详细说明:
1、客户端发送建立TCP连接的请求报文,其中报文中包含seq序列号,是由发送端随机生成的,并且将报文中的SYN字段置为1,表示需要建立TCP连接。(SYN=1,seq=x,x为随机生成数值);
2、服务端回复客户端发送的TCP连接请求报文,其中包含seq序列号,是由回复端随机生成的,并且将SYN置为1,而且会产生ACK字段,ACK字段数值是在客户端发送过来的序列号seq的基础上加1进行回复,以便客户端收到信息时,知晓自己的TCP建立请求已得到验证。(SYN=1,ACK=x+1,seq=y,y为随机生成数值)这里的ack加1可以理解为是确认和谁建立连接;
3、客户端收到服务端发送的TCP建立验证请求后,会使自己的序列号加1表示,并且再次回复ACK验证请求,在服务端发过来的seq上加1进行回复。(SYN=1,ACK=y+1,seq=x+1)。
由于TCP连接是全双工的,因此每个方向都必须单独进行关闭。这原则是当一方完成它的数据发送任务后就能发送一个FIN来终止这个方向的连接。收到一个 FIN只意味着这一方向上没有数据流动,一个TCP连接在收到一个FIN后仍能发送数据。首先进行关闭的一方将执行主动关闭,而另一方执行被动关闭。
四次挥手原理:
第1次挥手:客户端发送一个FIN,用来关闭客户端到服务端的数据传送,客户端进入FIN_WAIT_1状态;
第2次挥手:服务端收到FIN后,发送一个ACK给客户端,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号),服务端进入CLOSE_WAIT状态;
第3次挥手:服务端发送一个FIN,用来关闭服务端到客户端的数据传送,服务端进入LAST_ACK状态;
第4次挥手:客户端收到FIN后,客户端t进入TIME_WAIT状态,接着发送一个ACK给Server,确认序号为收到序号+1,服务端进入CLOSED状态,完成四次挥手。
其中:FIN标志位数置1,表示断开TCP连接。
可通过以下趣味图解理解四次挥手:
四次挥手过程详细说明:
1、客户端发送断开TCP连接请求的报文,其中报文中包含seq序列号,是由发送端随机生成的,并且还将报文中的FIN字段置为1,表示需要断开TCP连接。(FIN=1,seq=x,x由客户端随机生成);
2、服务端会回复客户端发送的TCP断开请求报文,其包含seq序列号,是由回复端随机生成的,而且会产生ACK字段,ACK字段数值是在客户端发过来的seq序列号基础上加1进行回复,以便客户端收到信息时,知晓自己的TCP断开请求已经得到验证。(FIN=1,ACK=x+1,seq=y,y由服务端随机生成);
3、服务端在回复完客户端的TCP断开请求后,不会马上进行TCP连接的断开,服务端会先确保断开前,所有传输到A的数据是否已经传输完毕,一旦确认传输数据完毕,就会将回复报文的FIN字段置1,并且产生随机seq序列号。(FIN=1,ACK=x+1,seq=z,z由服务端随机生成);
4、客户端收到服务端的TCP断开请求后,会回复服务端的断开请求,包含随机生成的seq字段和ACK字段,ACK字段会在服务端的TCP断开请求的seq基础上加1,从而完成服务端请求的验证回复。(FIN=1,ACK=z+1,seq=h,h为客户端随机生成)
至此TCP断开的4次挥手过程完毕。
LISTEN:等待从任何远端TCP 和端口的连接请求。
SYN_SENT:发送完一个连接请求后等待一个匹配的连接请求。
SYN_RECEIVED:发送连接请求并且接收到匹配的连接请求以后等待连接请求确认。
ESTABLISHED:表示一个打开的连接,接收到的数据可以被投递给用户。连接的数据传输阶段的正常状态。
FIN_WAIT_1:等待远端TCP 的连接终止请求,或者等待之前发送的连接终止请求的确认。
FIN_WAIT_2:等待远端TCP 的连接终止请求。
CLOSE_WAIT:等待本地用户的连接终止请求。
CLOSING:等待远端TCP 的连接终止请求确认。
LAST_ACK:等待先前发送给远端TCP 的连接终止请求的确认(包括它字节的连接终止请求的确认)
TIME_WAIT:等待足够的时间过去以确保远端TCP 接收到它的连接终止请求的确认。
TIME_WAIT 两个存在的理由:
1.可靠的实现tcp全双工连接的终止;
2.允许老的重复分节在网络中消逝。
CLOSED:不在连接状态(这是为方便描述假想的状态,实际不存在)。
图解TCP的三次握手和四次挥手(简单明了)
标志位:
SYN: 表示连接请求
ACK: 表示确认
FIN: 表示关闭连接
序号:
seq:表示报文序号
ack: 表示确认序号
(1)图示三次握手:
1~~~第一次握手:Client将标志位SYN置为1,随机产生一个值seq=J,并将该数据包发送给Server,Client进入
SYN_SENT状态,等待Server确认。
2~~~第二次握手:Server收到数据包后由标志位SYN=1知道Client请求建立连接,Server将标志位SYN和ACK都置为1,
ack (number )=J+1,随机产生一个值seq=K,
并将该数据包发送给Client以确认连接请求,Server进入SYN_RCVD状态。
3~~~第三次握手:Client收到确认后,检查ack是否为J+1,ACK是否为1,如果正确则将标志位ACK置为1,ack=K+1,
并将该数据包发送给Server,Server检查ack是否为K+1,ACK是否为1,如果正确则连接建立成功,
Client和Server进入ESTABLISHED状态,完成三次握手,随后Client与Server之间可以开始传输数据
了。
(2)图示四次挥手:
1++++第一次挥手:Client发送一个FIN,用来关闭Client到Server的数据传送。
2++++第二次挥手:Server收到FIN后,发送一个ACK给Client,确认序号为收到序号+1。
3++++第三次挥手:Server发送一个FIN,用来关闭Server到Client的数据传送。
4++++第四次挥手:Client收到FIN后,接着发送一个ACK给Server,确认序号为收到序号+1。
0条大神的评论