前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >TCP连接的建立(三次握手)和释放(四次挥手)

TCP连接的建立(三次握手)和释放(四次挥手)

作者头像
汤高
发布2018-01-11 17:12:59
8720
发布2018-01-11 17:12:59
举报
文章被收录于专栏:积累沉淀积累沉淀积累沉淀

所谓三次握手(Three-way Handshake),是指建立一个TCP连接时,需要客户端和服务器总共发送3个包。

 三次握手的目的是连接服务器指定端口,建立TCP连接,并同步连接双方的序列号和确认号并交换 TCP 窗口大小信息.在socket编程中,客户端执行connect()时。将触发三次握手

  • 第一次握手: 客户端发送一个TCP的SYN标志位置1的包指明客户打算连接的服务器的端口,以及初始序号X,保存在包头的序列号(Sequence Number)字段里。
  • 第二次握手: 服务器发回确认包(ACK)应答。即SYN标志位和ACK标志位均为1同时,将确认序号(Acknowledgement Number)设置为客户的I S N加1以.即X+1
  • 第三次握手. 客户端再次发送确认包(ACK) SYN标志位为0,ACK标志位为1.并且把服务器发来ACK的序号字段+1,放在确定字段中发送给对方.并且在数据段放写ISN的+1

       三次握手图

连接终止协议(四次挥手)    由于TCP连接是全双工的,因此每个方向都必须单独进行关闭。这原则是当一方完成它的数据发送任务后就能发送一个FIN来终止这个方向的连接。收到一个 FIN只意味着这一方向上没有数据流动,一个TCP连接在收到一个FIN后仍能发送数据。首先进行关闭的一方将执行主动关闭,而另一方执行被动关闭。  (1) TCP客户端发送一个FIN,用来关闭客户到服务器的数据传送  (2) 服务器收到这个FIN,它发回一个ACK,确认序号为收到的序号加1。和SYN一样,一个FIN将占用一个序号。  (3) 服务器关闭客户端的连接,发送一个FIN给客户端  (4) 客户段发回ACK报文确认,并将确认序号设置为收到序号加1 CLOSED: 这个没什么好说的了,表示初始状态—— 关闭。 LISTEN: 这个也是非常容易理解的一个状态,表示服务器端的某个SOCKET处于监听状态,可以接受连接了。 SYN_RCVD: 这个状态表示收到和发送一个连接请求后等待对方对连接请求的确认。当收到客户端的ACK报文后确认后,它会进入到ESTABLISHED状态。 SYN_SENT: 这个状态与SYN_RCVD遥想呼应,表示在发送连接请求后等待匹配的的连接请求

ESTABLISHED:这个容易理解了,表示连接已经建立了

四处挥手图解

FIN_WAIT_1: 这个状态等待远程TCP的连接中断请求或者对方对自己先前发送的连接中断请求的确认 FIN_WAIT_2:该状态表示等待远程TCP连接中断请求 TIME_WAIT: 表示收到了对方的FIN报文,并发送出了ACK报文,就等2MSL后即可回到CLOSED可用状态了。如果FIN_WAIT_1状态下,收到了对方同时带FIN标志和ACK标志的报文时,可以直接进入到TIME_WAIT状态,而无须经过FIN_WAIT_2状态。等待足够长的时间以确保远程TCP收到连接中断请求的确认 CLOSING: 这种状态比较特殊,实际情况中应该是很少见,属于一种比较罕见的例外状态。正常情况下,当你发送FIN报文后,按理来说是应该先收到(或同时收到)对方的ACK报文,再收到对方的FIN报文。但是CLOSING状态表示你发送FIN报文后,并没有收到对方的ACK报文,反而却也收到了对方的FIN报文。什么情况下会出现此种情况呢?其实细想一下,也不难得出结论:那就是如果双方几乎在同时close一个SOCKET的话,那么就出现了双方同时发送FIN报文的情况,也即会出现CLOSING状态,表示双方都正在关闭SOCKET连接。 CLOSE_WAIT: 这种状态的含义其实是表示在等待关闭。怎么理解呢?当对方close一个SOCKET后发送FIN报文给自己,你系统毫无疑问地会回应一个ACK报文给对方,此时则进入到CLOSE_WAIT状态。接下来呢,实际上你真正需要考虑的事情是察看你是否还有数据发送给对方,如果没有的话,那么你也就可以close这个SOCKET,发送FIN报文给对方,也即关闭连接。所以你在CLOSE_WAIT状态下,需要完成的事情是等待你去关闭连接也就是说——等待从本地发送的连接中断请求。 LAST_ACK: 这个状态表示等待原来发向远程TCP的连接中断请求的确认。当收到ACK报文后,也即可以进入到CLOSED可用状态了。 1、 为什么建立连接协议是三次握手,而关闭连接却是四次握手呢? 这是因为服务端的LISTEN状态下的SOCKET当收到SYN报文的建连请求后,它可以把ACK和SYN(ACK起应答作用,而SYN起同步作用)放在一个报文里来发送。但关闭连接时,当收到对方的FIN报文通知时,它仅仅表示对方没有数据发送给你了;但未必你所有的数据都全部发送给对方了,所以你可能未必会马上会关闭SOCKET,也即你可能还需要发送一些数据给对方之后,再发送FIN报文给对方来表示你同意现在可以关闭连接了,所以它这里的ACK报文和FIN报文多数情况下都是分开发送的。 2、 为什么TIME_WAIT状态还需要等2MSL后才能返回到CLOSED状态? 这是因为:虽然双方都同意关闭连接了,而且握手的4个报文也都协调和发送完毕,按理可以直接回到CLOSED状态(就好比从SYN_SEND状态到ESTABLISH状态那样);但是因为我们必须要假想网络是不可靠的,你无法保证你最后发送的ACK报文会一定被对方收到,因此对方处于LAST_ACK状态下的SOCKET可能会因为超时未收到ACK报文,而重发FIN报文,所以这个TIME_WAIT状态的作用就是用来重发可能丢失的ACK报文。

最后我直接画了一张整个流程的图  字写得不好 大家得看且看 不要笑话

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2015-11-15 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档