据说面试很爱问TCP的问题,我看了个学习视频TCP的三次握手,然后记录一下
为什么tcp三次握手是三次、而不是两次、四次呢?
tcp的三次握手就是确保双方都有接收和发送的能力,而且对方都明确知道这个能力
看网上个例子顿时就清晰了,特此记录一下
以谈恋爱为例,两个人能够在一起最重要的事情就是首先确认各自爱和被爱的能力,模拟三次握手的过程。
第一次:
男说:我爱你。女方收到。 由此证明男方拥有爱的能力。
第二次:
女:我收到了你的爱,我也爱你。 男方收到。 现在情况说明女方拥有爱和被爱的能力。
第三次:
男:我收到了你的爱。 女方收到。现在能够保证男方具备被爱的能力。由此完整的确认了双方爱和被爱的能力。
刚才的例子会发现传输三次那正好对方都能明确信息的接收,不会出现信息理解的错乱,对应到TCP的三次握手,也是需要确认双方的两样能力:发送的能力和接收的能力。
为啥tcp不是两次握手呢?
根本原因:无法确认客户端的接收能力。
为什么不是四次?
三次握手的目的是确认双方发送
和接收
的能力,那四次握手可以嘛?当然可以,100 次都可以。但为了解决问题,三次就足够了,再多用处就不大了。
三次握手过程中可以携带数据么?
第三次握手的时候,可以携带。前两次握手不能携带数据。
如果前两次握手能够携带数据,那么一旦有人想攻击服务器,那么他只需要在第一次握手中的 SYN 报文中放大量数据,那么服务器势必会消耗更多的时间和内存空间去处理这些数据,增大了服务器被攻击的风险。
第三次握手的时候,客户端已经处于ESTABLISHED
状态,并且已经能够确认服务器的接收、发送能力正常,这个时候相对安全了,可以携带数据。
1.再说三次握手之前说一下三次握手操作的字段
- Seq:Seq序号,用来标识从TCP源端向目的端发送的字节流,发起方发送数据时对此进行标记。
- 确认号:Ack序号,只有ACK标志位为1时,确认序号字段才有效,Ack=Seq+1。
- 标志位(Flags):共6个,即URG、ACK、PSH、RST、SYN、FIN等;含义如 下
注意:不要将确认序号Ack和标志位中的ACK弄混了,确认方Ack=发起方Seq+1,两端配对。
2.图解分析TCP的三次握手协议
视频学习图
网图
- 1.首先必须要有用户也就是客户端来打开连接,客户端也就结束了closed阶段,被动打开的服务端也结束closed的阶段,并进行监听(LISTEN),随后开始“三次握手”
- 2.第一次握手,现在客户端要连接,所以像服务端发送报文了,标志位为SYN,表示"请求建立连接",序号为X(X一般为1),然后客户端进入同步发送(SYN_SEND)状态,等待服务器确认
- 3.第二次握手:服务端接到客户端发送的包,结束了监听(LISTEN),并返回一段TCP报文:标志位SYN和ACK(ACK一般为1是有效),表示:确认客户端的报文序号(Seq)有效,服务器能正常接收数据,同意创建连接。序号为Seq=y,确认号为Ack=x+1,此时服务器进入同步接收(SYN_RECV)状态
- 4.第三次握手:客户端收到服务端的确认数据的TCP报文之后,明确了从客户端到服务端的数据是传输正常的,结束同步发送状态(SYN_SEND)并返回最后一段TCP报文:标志位ACK,表示连接有效,序号为Seq=x+1,表示收到服务器端序号Seq并将其值加1作为自己的确认号Ack的值;确认号为Ack=y+1,表示收到服务器端序号Seq,并将其加1作为自己的确认号Ack的值 ,随后客户端进入连接状态(ESTABLISHED),完成三次握手。
- 服务端收到客户端的TCP报文之后,知道了服务端到客户端的数据传输是正常的,结束了同步接收(SYN_RECV)状态,进入到ESTABLISHED阶段。
在客户端与服务器端传输的TCP报文中,双方的确认号Ack和序号Seq的值,都是在彼此Ack和Seq值的基础上进行计算的,这样做保证了TCP报文传输的连贯性。一旦出现某一方发出的TCP报文丢失,便无法继续"握手",以此确保了"三次握手"的顺利完成。
此后客户端和服务端进行正常的数据传输。这就是“三次握手”的过程。
也就是说建立连接会进行确认,然后客户端状态会从关闭--》打开连接--》同步发送--》建立连接
服务端:状态关闭--》打开--》监听--》同步接收--》建立连接
2.为什么要三次握手?
主要是为了防止已经失效的连接请求报文段突然又传到了服务端,因而报文错乱问题
假定客户端发出第一个连接请求报文段并没有丢失二是在某些网络节点长时间滞留了,一直延迟到连接释放以后的某个时间才到达服务端,本来这是一个早已失效的报文段,但是服务端收到此失效的连接请求段文后,就误认为是客户端又发出一次新的连接请求,于是就向客户端发出确认报文段,同意建立连接,假定不采用三次握手、那么只要服务端发出确认,新的连接就建立了,这样一直等待客户端发来数据,服务端的许多资源就白白浪费了
3.TCP的四次挥手
你知道TCP的四次挥手么?为什么要进行四次挥手?
确保数据能够完整传输,当被动方收到主动方的FIN报文通知时,它仅仅表示主动没有数据再发送给被动方了,但未必被动方所有的数据都完整的发送给了主动方,所以被动方不会马上关闭连接,它可能还需要发送一些数据给主动方后再发送FIN报文给主动方,告诉主动方同意关闭连接,所以这里的ACK报文和FIN报文多数情况下都是分开发送的。
“挥手”代表TCP连接的释放。连接的释放必须是一方主动释放,另一方被动释放
挥手前主动释放连接的客户端结束ESTABLISHED阶段,随后开始四次挥手
1.第一次挥手,客户端想要释放连接,向服务端发送一段TCP报文:标记为FIN,表示“请求释放连接”,序号为Seq=U。随后客户端进入到等待(FIN-WAIT-1)状态,即半关闭阶段,客户端此时不允许对服务端发送数据,但是可以接收从服务器端传输过来的数据
2.第二次挥手,服务端接收到客户端发出的TCP报文后,知道了客户心想要释放连接,随后服务端也结束了ESTABLISHED阶段,进入到关闭等待阶段(半关闭状态)并返回TCP报文:标志位ACK,表示"接收到客户端发送的释放连接的请求";序号为Seq=V;确认号为Ack=U+1,表示是在收到客户端报文的基础上,将其序号Seq值加1作为本短报文确认号Ack的值;随后服务器端开始准备释放服务器端到客户端方向上的连接。
3.第三次挥手:当服务端传输完毕后,服务端发出连接释放报文段(FIN=1,ACK=1,序号Seq=w,确认号ack=u+1),服务端进入最后确认状态(LAST-ACK),等待客户端的最后确认。
4.第四次挥手:客户端收到服务端的连接释放报文段后,对此发出确认报文段(ACK=1,Seq=u+1,ack=w+1),客户端进入时间等待(TIME-WAIT)状态,此时TCP未释放掉,需要经过时间等待计时器设置的时间2MSL后,客户端才进入到关闭状态。