当前位置: 移动技术网 > IT编程>开发语言>Java > TCP/IP协议中三次握手四次挥手的原理及流程分析

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

2019年07月19日  | 移动技术网IT编程  | 我要评论

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

先来看看原理图:

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协议中三次握手四次挥手的原理及流程分析的全部内容,希望对大家有所帮助。如有不足之处,欢迎留言指出,期待您的宝贵意见。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网