欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

TCP/IP协议中三次握手四次挥手的原理及流程分析

程序员文章站 2023-12-16 21:57:46
当初学的是通信专业,毕业以后,同学们各奔东西,去追逐自己的梦想,奔波于大大小小的工地之间。哈哈,开个玩笑,也有厉害的,进了某某研究所,嗯?他爸不是所长,内心不要太阴暗。记得...

当初学的是通信专业,毕业以后,同学们各奔东西,去追逐自己的梦想,奔波于大大小小的工地之间。哈哈,开个玩笑,也有厉害的,进了某某研究所,嗯?他爸不是所长,内心不要太阴暗。记得有一门十分高大上的课程,名字叫做计算机网络(大概是这个名字吧)。里面有一个关于握手的概念,现在温习一下。

先来看看原理图:

TCP/IP协议中三次握手四次挥手的原理及流程分析

tcp是面向连接的,无论哪一方向另一方发送数据之前,都必须先在双方之间建立一条连接。在tcp/ip协议中,tcp 协议提供可靠的连接服务,连接是通过三次握手进行初始化的。三次握手的目的是同步连接双方的序列号和确认号 并交换 tcp窗口大小信息。

1.第一次握手:建立连接。客户端发送连接请求报文段,将syn位置为1,sequence number为x;然后,客户端进入syn_send状态,等待服务器的确认;

2.第二次握手:服务器收到syn报文段。服务器收到客户端的syn报文段,需要对这个syn报文段进行确认,设置acknowledgment number为x+1(sequence number+1);同时,自己自己还要发送syn请求信息,将syn位置为1,sequence number为y;服务器端将上述所有信息放到一个报文段(即syn+ack报文段)中,一并发送给客户端,此时服务器进入syn_recv状态;

3.第三次握手:客户端收到服务器的syn+ack报文段。然后将acknowledgment number设置为y+1,向服务器发送ack报文段,这个报文段发送完毕以后,客户端和服务器端都进入established状态,完成tcp三次握手。

完成了三次握手,客户端和服务器端就可以开始传送数据。以上就是tcp三次握手的总体介绍。

那四次挥手呢?

当客户端和服务器通过三次握手建立了tcp连接以后,当数据传送完毕,肯定是要断开tcp连接的啊。那对于tcp的断开连接,这里就有了神秘的“四次挥手”。

1.第一次挥手:主机1(可以使客户端,也可以是服务器端),设置sequence number和acknowledgment number,向主机2发送一个fin报文段;此时,主机1进入fin_wait_1状态;这表示主机1没有数据要发送给主机2了;

2.第二次挥手:主机2收到了主机1发送的fin报文段,向主机1回一个ack报文段,acknowledgment number为sequence number加1;主机1进入fin_wait_2状态;主机2告诉主机1,我也没有数据要发送了,可以进行关闭连接了;

3.第三次挥手:主机2向主机1发送fin报文段,请求关闭连接,同时主机2进入close_wait状态;

4.第四次挥手:主机1收到主机2发送的fin报文段,向主机2发送ack报文段,然后主机1进入time_wait状态;主机2收到主机1的ack报文段以后,就关闭连接;此时,主机1等待2msl后依然没有收到回复,则证明server端已正常关闭,那好,主机1也可以关闭连接了。

至此,tcp的四次挥手就这么愉快的完成了。当你看到这里,你的脑子里会有很多的疑问,很多的不懂,感觉很凌乱;没事,我们继续总结。

为什么要三次握手?

所谓三次握手(three-way handshake)即建立tcp连接,就是指建立一个tcp连接时,需要客户端和服务端总共发送3个包以确认连接的建立。在socket编程中,这一过程由客户端执行connect来触发。

既然总结了tcp的三次握手,那为什么非要三次呢?怎么觉得两次就可以完成了。那tcp为什么非要进行三次连接呢?在谢希仁的《计算机网络》中是这样说的:

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

在书中同时举了一个例子,如下:

"已失效的连接请求报文段”的产生在这样一种情况下:client发出的第一个连接请求报文段并没有丢失,

而是在某个网络结点长时间的滞留了,以致延误到连接释放以后的某个时间才到达server。本来这是一

个早已失效的报文段。但server收到此失效的连接请求报文段后,就误认为是client再次发出的一个新

的连接请求。于是就向client发出确认报文段,同意建立连接。假设不采用“三次握手”,那么只要server

发出确认,新的连接就建立了。由于现在client并没有发出建立连接的请求,因此不会理睬server的确认,

也不会向server发送数据。但server却以为新的运输连接已经建立,并一直等待client发来数据。这样,

server的很多资源就白白浪费掉了。采用“三次握手”的办法可以防止上述现象发生。例如刚才那种情况,

client不会向server的确认发出确认。server由于收不到确认,就知道client并没有要求建立连接。"

这就很明白了,防止了服务器端的一直等待而浪费资源。

为什么要四次挥手?

那四次挥手又是为何呢?

所谓四次挥手(four-way wavehand)即终止tcp连接,就是指断开一个tcp连接时,需要客户端和服务端总共发送4个包以确认连接的断开。在socket编程中,这一过程由客户端或服务端任一方执行close来触发。

tcp协议是一种面向连接的、可靠的、基于字节流的运输层通信协议。tcp是全双工 模式,这就意味着,当主机1发出fin报文段时,只是表示主机1已经没有数据要发送了,主机1告诉主机2, 它的数据已经全部发送完毕了;但是,这个时候主机1还是可以接受来自主机2的数据;当主机2返回ack报文 段时,表示它已经知道主机1没有数据发送了,但是主机2还是可以发送数据到主机1的;当主机2也发送了fin 报文段时,这个时候就表示主机2也没有数据要发送了,就会告诉主机1,我也没有数据要发送了,之后彼此 就会愉快的中断这次tcp连接。如果要正确的理解四次挥手的原理,就需要了解四次挥手过程中的状态变化。

fin_wait_1: 这个状态要好好解释一下,其实fin_wait_1和fin_wait_2状态的真正含义都是表示等 待对方的fin报文。而这两种状态的区别是:fin_wait_1状态实际上是当socket在established状态时, 它想主动关闭连接,向对方发送了fin报文,此时该socket即进入到fin_wait_1状态。而当对方回应ack报 文后,则进入到fin_wait_2状态,当然在实际的正常情况下,无论对方何种情况下,都应该马上回应ack 报文,所以fin_wait_1状态一般是比较难见到的,而fin_wait_2状态还有时常常可以用netstat看到。 (主动方)

fin_wait_2:上面已经详细解释了这种状态,实际上fin_wait_2状态下的socket,表示半连接,也即 有一方要求close连接,但另外还告诉对方,我暂时还有点数据需要传送给你(ack信息),稍后再关闭连接。 (主动方)

close_wait:这种状态的含义其实是表示在等待关闭。怎么理解呢?当对方close一个socket后发送fin 报文给自己,你系统毫无疑问地会回应一个ack报文给对方,此时则进入到close_wait状态。接下来呢,实 际上你真正需要考虑的事情是察看你是否还有数据发送给对方,如果没有的话,那么你也就可以 close这个 socket,发送fin报文给对方,也即关闭连接。所以你在close_wait状态下,需要完成的事情是等待你去关 闭连接。(被动方)

last_ack: 这个状态还是比较容易好理解的,它是被动关闭一方在发送fin报文后,最后等待对方的ack报 文。当收到ack报文后,也即可以进入到closed可用状态了。(被动方)

time_wait: 表示收到了对方的fin报文,并发送出了ack报文,就等2msl后即可回到closed可用状态了。 如果finwait1状态下,收到了对方同时带fin标志和ack标志的报文时,可以直接进入到time_wait状态,而无 须经过fin_wait_2状态。(主动方)

closed: 表示连接中断。

总结

 以上就是本文关于tcp/ip协议中三次握手四次挥手的原理及流程分析的全部内容,希望对大家有所帮助。如有不足之处,欢迎留言指出,期待您的宝贵意见。

上一篇:

下一篇: