网站改版灵感库,个人创业众筹平台,深圳网站建设加盟,温州网络问政TCP 建链#xff08;三次握手#xff09;和断链#xff08;四次挥手#xff09; 背景简介建链#xff08;三次握手#xff09;断链#xff08;四次挥手#xff09;序号及标志位延伸问题为什么建立连接需要握手三次#xff0c;两次行不行#xff1f;三次握手可以携带数… TCP 建链三次握手和断链四次挥手 背景简介建链三次握手断链四次挥手序号及标志位延伸问题为什么建立连接需要握手三次两次行不行三次握手可以携带数据吗为什么释放连接是四次比建立连接多一次为什么 TIME_WAIT 状态需要经过 2MSL 才能返回到 CLOSED 状态 背景
随着年龄的增长很多曾经烂熟于心的技术原理已被岁月摩擦得愈发模糊起来技术出身的人总是很难放下一些执念遂将这些知识整理成文以纪念曾经努力学习奋斗的日子。本文内容并非完全原创大多是参考其他文章资料整理所得感谢每位技术人的开源精神。
简介
本文介绍 TCP 的建链和断链过程即通常所说的三次握手和四次挥手的过程。
建链三次握手
TCP 建链需要客户端与服务器之间交互 3 个数据包主要作用就是为了确认双方的接收和发送能力是否正常初始序列号、交换窗口大小以及 MSS 等信息。 第一次握手 客户端发送请求连接数据包到服务器标志位 SYN 置为 1随机生成一个初始序号 seq 即 SYN1 seqx客户端从 CLOSED 状态进入 SYN_SENT 状态等待服务器回复。 第二次握手 服务器收到请求数据包后根据标志位 SYN1 知道客户端在请求建立连接服务器将标志位 SYN 和 ACK 都置为 1确认序号 ackx1随机生成一个初始序号 seqy并将该数据包 SYN1, ACK1, seqy, ackx1 回复给客户端确认连接请求服务器从 LISTEN 状态进入 SYN_RCVD 状态。 第三次握手 客户端收到确认后检查确认序号 ack 是否为 x1ACK 是否为 1如果正确则将标志位 ACK 置为1确认序号 acky1并将该数据包 ACK1, seqx1, acky1 发送给服务器发送完成后客户端进入 ESTABLISHED 状态服务器接收到后检查确认序号 ack 是否为 y1如果正确则连接建立成功服务器进入 ESTABLISHED 状态。随后客户端与服务器间可以开始传输数据。
断链四次挥手 第一次挥手 客户端发起 FIN 包 FIN1, ACK1, sequ, ackv客户端从 ESTABLISHED 状态进入 FIN_WAIT_1 状态。TCP 协议规定即使 FIN 包不携带数据也要消耗一个序号。此 FIN 包中 ACK1 和 ackv 基于断链前正常通信的数据包。 第二次挥手 服务器收到 FIN 包发出 ACK 确认包并带上自己的序号 seqvACK1 seqv acku1服务器进入从 ESTABLISHED 状态进入 CLOSE_WAIT 状态。此时客户端已经没有数据需要发送给服务器了但服务器如果仍有数据发送给客户端的话客户端依然需要接收。客户端接收到服务器发送的 ACK 后进入 FIN_WAIT_2 状态。 第三次挥手 服务器数据发送完成后向客户端发送 FIN 包 FIN1, ACK1, seqw, acku1半连接状态下服务器可能又发送了一些数据假设发送 seq 为 w服务器进入 LAST_ACK 状态。 第四次挥手 客户端接收到服务器的 FIN 包后发出确认包 ACK1, sequ1, ackw1客户端进入 TIME_WAIT 状态此时 TCP 连接还没有释放必须经过 2*MSL 后才进入 CLOSED 状态而服务器接收到客户端的 ACK 后就进入了 CLOSED 状态服务器结束 TCP 连接的时间要比客户端早一些。
序号及标志位
TCP 建链三次握手和断链四次挥手中涉及到几个关键概念字段
标志位共有 6 个分别是 ACK确认序号有效。FIN释放一个连接。PSH接收方应该尽快将这个报文交给应用层。RST重置连接。SYN发起一个新连接。URG紧急指针urgent pointer有效。 seqSeq 序号占 32 位用来标识从 TCP 源端向目的端发送的字节流发起方发送数据时对此进行标记。ackAck 序号占 32 位只有 ACK 标志位等于 1 时此序号字段才有效确认方 ack 等于发起方 seq 1。注意ACK 和 ack 是两个不同的概念不要混淆了。
延伸问题
为什么建立连接需要握手三次两次行不行
原因一TCP连接建立前需要确认客户端和服务器双方的收发包能力。 第一次握手可以让服务器知道客户端的发送能力是正常的。第二次握手可以让客户端知道服务器的接收和发送能力都是正常的。第三次握手可以让服务器指导客户端的接收能力是正常的。 原因二确保序列号可靠同步。 第二次握手服务器向客户端发送了自己的初始序列号如果第二次握手报文丢失则客户端就无法知道服务器的初始序列号所以需要第三次握手让服务器知道客户端已确认服务器的初始序列号。原因三阻止重复历史连接的初始化。 客户端由于某种原因发送了两个不同序号的 SYN 包因为复杂的网络环境中旧的数据包有可能先到达服务器如果是两次握手则服务器收到旧的 SYN 包就会立刻建立连接从而造成网络异常。如果是三次握手服务器需要回复 SYNACK 包客户端会对比应答的序号如果发现是旧的报文就会给服务器发 RST 包直至正确的 SYN 包到达服务器后才正常建立连接。原因四安全问题。 TCP 新建连接时内核会为连接分配一系列内存资源如果采用两次握手可能会放大DDOS 攻击。
三次握手可以携带数据吗
第一次握手和第二次握手不可以携带数据第三次握手可以携带数据。假如第一次握手携带数据如果碰到恶意攻击那么每次在第一次握手的 SYN 报文中都会加入大量数据会造成服务器花费大量存储空间来缓存这些数据。
为什么释放连接是四次比建立连接多一次
建立连接时服务器的 SYN 和 ACK 是合并发送的而因 TCP 是全双工通信释放连接过程中在客户端发送 FIN 包后服务器可能还有数据需要发送不能立即关闭连接所以不能同时发送 FIN 包和 ACK 包只能先确认 ACK然后等服务器无数据发送时再发送 FIN 包。
为什么 TIME_WAIT 状态需要经过 2MSL 才能返回到 CLOSED 状态
MSL 是指报文在网络中的最大生存时间。
原因一在客户端回复服务器 FIN 包的确认包 ACK 后这个 ACK 包可能是不可达的如果服务器收不到 ACK 的话需要重新发送 FIN 包。所以客户端发送 ACK 后需要留出 2MSL 时间ACK 到达服务器的时间 服务器重发 FIN 包时间如果客户端等到 2MSL 后没有收到服务器重传的 FIN 包说明可以确认服务器已经收到了客户端发送的 ACK 包。原因二客户端发送完最后一个 ACK 包后再经过 2MSL 时间就可以使当前连接持续的时间内所产生的所有报文都从网络中小时使下一个新的连接中不会出现这种旧的连接请求报文。