1.http通信为甚么要三次握手,四次挥手;
当客户端发出第一个连接请求报文段时并没有丢失,而是在某个网络节点出现了长时间的滞留,以至于延误了连接请求在某个时间之后才到达服务器。这应该是一个早已失效的报文段。但是服务器在收到此失效的连接请求报文段后,以为是客户端的一个新请求,于是就向客户端发出了确认报文段,同意建立连接。假设不采用三次握手,那么只要服务器发出确认后,新的连接就可以建立了。但是由于客户端没有发出建立连接的请求,因此不会管服务器的确认,也不会向服务器发送数据,但服务器却以为新的运输连接已经建立,一直在等待,所以服务器的资源就白白浪费了
如果在TCP第三次握手中的报文段丢失了会出现什么情况?
客户端会认为此连接已建立,如果客户端向服务器发送数据,服务器将以RST包响应,这样就能感知到服务器的错误了。为什么要四次挥手
为了保证在最后断开的时候,客户端能够发送最后一个ACK报文段能够被服务器接收到。如果客户端在收到服务器给它的断开连接的请求之后,回应完服务器就直接断开连接的话,若服务器没有收到回应就无法进入CLOSE状态,所以客户端要等待两个最长报文段寿命的时间,以便于服务器没有收到请求之后重新发送请求。
防止“已失效的连接请求报文”出现在连接中,在释放连接的过程中会有一些无效的滞留报文,这些报文在经过2MSL的时间内就可以发送到目的地,不会滞留在网络中。这样就可以避免在下一个连接中出现上一个连接的滞留报文了
三次握手建立连接,形象的打电话场景:
- 第一次握手(拨号)
→ 你(客户端):“喂,能听到吗?我要和你说话!”(发送SYN=1,并随机生成一个序号seq=J)
作用:确认你的手机能发送声音,朋友手机能接收声音。但朋友还不知道自己是否能发送声音。
- 第二次握手(朋友回应)
→ 朋友(服务端):“听到了!你能听到我吗?”(发送SYN=1和ACK=1,确认号ack=J+1,随机生成序号seq=K)
作用:朋友确认自己手机能接收和发送声音,你也确认了对方能接收声音。但你仍需回应,否则朋友不知道你能否接收他的声音。
- 第三次握手(确认能听到回应)
→ 你:“能听到!”(发送ACK=1,确认号ack=K+1)
作用:朋友确认你的手机能接收声音。至此,双方确认通话正常,开始聊天(传输数据)
四次挥手:断开连接(双方确认结束通话)
- 第一次挥手(你提出挂断)
→ 你:“我说完了,先挂啦!”(发送FIN=1,序号seq=U)
作用:你不再发送数据,但仍能接收朋友说的话。
- 第二次挥手(朋友回应)
→ 朋友:“好的,稍等!”(发送ACK=1,确认号ack=U+1)
作用:朋友知道你要挂断,但可能还有话没说完(比如最后一句“明天见”)。
第三次挥手(朋友确认挂断)
→ 朋友:“我也说完了,可以挂了!”(发送FIN=1,确认号ack=U+1,序号seq=W)
作用:朋友确认数据发送完毕,可以关闭连接。
第四次挥手(你最后确认)
→ 你:“收到,拜拜!”(发送ACK=1,确认号ack=W+1)
作用:朋友收到后彻底挂断。你需等待片刻(TIME_WAIT状态),防止朋友没听到“拜拜”而重拨(重传FIN)
记忆口诀
三次握手:一喊(SYN)、二应(SYN+ACK)、三确认(ACK)
四次挥手:一说(FIN)、二答(ACK)、三回(FIN)、四关(ACK)