首页 > 编程知识 正文

tcp握手挥手协议过程,tcp三次握手协议

时间:2023-05-03 12:38:18 阅读:273627 作者:1318

TCP建立连接和断开连接很重要,但是自己又经常忘记一些具体细节,回顾的时候要么到收藏夹里找文章,要么是百度/谷歌一波,偶尔一两次还好,次数多了略显麻烦,遂趁这次温故的机会,记录下来,方便自己也方便他人~

TCP报文格式

TCP报文格式如下图所示:

其中有几个字段比较重要,在下面讲三次握手和四次挥手是会用到:

序号:seq序号,占32位,用来标识从TCP源端向目的端发送的字节流,发起方发送数据时对此进行标记;确认序号:ack序号,占32位,只有ACK标志位为1时,确认序号字段才有效;标志位:共6个,即URG、ACK、PSH、RST、SYN、FIN,每个标志位表示一个控制空能,具体如下: URG:紧急指针(urgent pointer),为1时表示紧急指针有效,为0则忽略紧急指针。紧急指针是一个正的偏移量,和序号字段中的值相加表示紧急数据最后一个字节的序号。TCP的紧急方式是发送端向另一端发送紧急数据的一种方式;ACK:确认序号,为1时表示确认号有效,为0表示报文中不含确认信息,忽略确认号字段;PSH:PUSH标志,为1表示是带有PUSH标志的数据,指示接收方在接收到该报文段以后,应尽快将这个报文段交给应用程序,而不是在缓冲区排队;RST:重置/复位连接,用于重置由于主机崩溃或其他原因而出现错误的连接。或者用于拒绝非法的报文段和拒绝连接请求;SYN:同步序号,用于建立连接过程;FIN:FINISH标志,释放连接,为1时表示发送方已经没有数据发送了,即关闭本方数据流。

需要特别注意

确认序号ack与标志位ACK不同,不能混淆,看下面就会懂;确认方的确认序号ack等于发起方的序号seq加1,即ack=seq+1,才能够两端匹配。 三次握手(建立TCP连接)

三次握手(Three-Way Handshake)即建立TCP连接,指建立一个TCP连接时,需要客户端和服务端总共发送3个包来确认连接的建立,整个过程大致如下:

第一次握手:Client将标志位SYN置为1,随机产生一个值seq=J,并将该数据包发送给Server,Client进入SYN_SENT状态,等待Server确认。第二次握手:Server收到数据包后由标志位SYN=1知道Client请求建立连接,Server将标志位SYN和ACK都置为1,ack=J+1,随机产生一个值seq=K,并将该数据包发送给Client以确认连接请求,Server进入SYN_RCVD状态。第三次握手:Client收到确认后,检查ack是否为J+1,ACK是否为1,如果正确则将标志位ACK置为1,ack=K+1,并将该数据包发送给Server,Server检查ack是否为K+1,ACK是否为1,如果正确则连接建立成功,Client和Server进入ESTABLISHED状态,完成三次握手,随后Client与Server之间可以开始传输数据了。 半连接(half-open connect)

在三次握手过程中,第二次握手,即Server发送SYN-ACK之后,收到Client的ACK之前的TCP连接被称为半连接。

此时Server会将第一次握手相关信息放入半连接队列(syns queue)中,若收到第三次握手Client发送的ACK报文后,则将相关信息挪入全连接队列(accept queue),否则会有限次数(超时机制)的重传SYN-ACK。如果半连接队列或者全连接队列已满,则抛弃此次连接。

SYN攻击(半连接攻击):

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

三次握手的原因

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

举例:

Client发出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞留了,以致延误到连接释放以后的某个时间才到达Server。本来这是一个早已失效的报文段。但Server收到此失效的连接请求报文段后,就误认为是Client再次发出的一个新的连接请求。于是就向Client发出确认报文段,同意建立连接。假设不采用“三次握手”,那么只要Server发出确认,新的连接就建立了。由于现在Client并没有发出建立连接的请求,因此不会理睬Server的确认,也不会向Server发送数据。但Server却以为新的运输连接已经建立,并一直等待Client发来数据。这样,Server的很多资源就白白浪费掉了。采用“三次握手”的办法可以防止上述现象发生。例如刚才那种情况,Client不会向Server的确认发出确认。Server由于收不到确认,就知道Client并没有要求建立连接。

四次挥手(断开TCP连接)

四次挥手(Four-Way Wavehand)即断开TCP连接,指断开一个TCP连接时,需要客户端和服务端总共发送4个包以确认连接的断开。整个过程大致如下:

由于TCP连接时全双工的,因此,每个方向都必须要单独进行关闭,这一原则是当一方完成数据发送任务后,发送一个FIN来终止这一方向的连接,收到一个FIN只是意味着这一方向上没有数据流动了,即不会再收到数据了,但是在这个TCP连接上仍然能够发送数据,直到这一方向也发送了FIN。首先进行关闭的一方将执行主动关闭,而另一方则执行被动关闭,上图描述的即是如此。

第一次挥手:Client发送一个FIN,用来关闭Client到Server的数据传送,Client进入FIN_WAIT_1状态。第二次挥手:Server收到FIN后,发送一个ACK给Client,确认序号为收到序号seq+1(与SYN相同,一个FIN占用一个序号),Server进入CLOSE_WAIT状态。第三次挥手:Server发送一个FIN,用来关闭Server到Client的数据传送,Server进入LAST_ACK状态。第四次挥手:Client收到FIN后,Client进入TIME_WAIT状态,接着发送一个ACK给Server,确认序号为收到序号seq+1,同时等待2MSL(报文最大生存时间)进入CLOSED状态。Server收到ACK后进入CLOSED状态,完成四次挥手。 四次挥手的原因

TCP协议是一种面向连接的、可靠的、基于字节流的传输层全双工模式通信协议,这就意味着,当Client发出FIN报文段时,只是表示Client已经没有数据要发送了,Client告诉Server,它的数据已经全部发送完毕了;但是,这个时候Client还是可以接受来自Server的数据;当Server返回ACK报文段时,表示它已经知道Client没有数据发送了,但是Server还是可以发送数据到Client的;当Server也发送了FIN报文段时,这个时候才表示Server也没有数据要发送了,就会告诉Client,我也没有数据要发送了,之后彼此就会愉快的中断这次TCP连接。

Client进入TIME_WAIT状态后等待2MSL(报文最大生存时间)才进入CLOSED状态的原因 保证TCP协议的全双工连接能够可靠关闭

如果Client直接CLOSED了,那么由于IP协议的不可靠性或者是其它网络原因,导致Server没有收到Client最后回复的ACK。那么Server就会在超时之后继续发送FIN,此时由于Client已经CLOSED了,就找不到与重发的FIN对应的连接,最后Server就会收到RST而不是ACK,Server就会以为是连接错误把问题报告给高层。这样的情况虽然不会造成数据丢失,但是却导致TCP协议不符合可靠连接的要求。所以,Client不是直接进入CLOSED,而是要保持TIME_WAIT,当再次收到FIN的时候,能够保证对方收到ACK,最后正确的关闭连接。

保证这次连接的重复数据段从网络中消失

如果Client直接CLOSED,然后又再向Server发起一个新连接,我们不能保证这个新连接与刚关闭的连接的端口号是不同的。也就是说有可能新连接和老连接的端口号是相同的。一般来说不会发生什么问题,但是还是有特殊情况出现:假设新连接和已经关闭的老连接端口号是一样的,如果前一次连接的某些数据仍然滞留在网络中,这些延迟数据在建立新连接之后才到达Server,由于新连接和老连接的端口号是一样的,又因为TCP协议判断不同连接的依据是socket pair,于是,TCP协议就认为那个延迟的数据是属于新连接的,这样就和真正的新连接的数据包发生混淆了。所以TCP连接还要在TIME_WAIT状态等待2MSL,这样可以保证本次连接的所有数据都从网络中消失。

参考 TCP协议详解TCP报文格式详解简述TCP的三次握手过程一次完整的HTTP请求过程

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。