网络编程 TCP四次握手和常见问题的总结

网络编程 TCP四次握手和常见问题的总结

1):描述TCP四次握手的过程

第一次挥手,客户端发送一个FIN标志位为1的数据包给服务器,表面自己数据发送完毕,进入FIN_WAIT_1状态。

第二次挥手,服务端收到FIN后,回复一个ACK确认包给客户端,并进入CLOSE_WAIT状态,告诉客户端自己准备关闭连接。客户端接收到ack应答报文后,进入FIN_WAIT_2状态

第三次挥手,服务端数据发生完毕,准备好关闭连接,向客户端发送一个FIN标志位为1的数据包,进入LAST_ACK状态。

第四次挥手,客户端收到服务器的FIN后,发送ACK确认包给服务器,进入到TIME_WAIT状态,等到2MSL后关闭连接,服务器收到ACK后进入CLOSED状态,完成四次挥手。

四次挥手优化

当主动关闭方接收到ACK报文时,关闭方式有以下:

  1. close函数关闭:孤儿连接,若在tcp_fin_timeout秒内没有收到对方的FIN报文,则连接直接关闭,同时tcp_max_orphans定义了最大孤儿连接的数量,超过直接释放
  2. shutdown函数关闭

当TIME_WAIT状态过多时,可通过tcp_tw_reusetcp_timestamps为1,将TIME_WAIT状态的端口复用于作为客户端的新连接(只适用于客户端)。

2):四次挥手过程当中,客户端和服务器各自的状态变化是什么?

客户端 FIN_WAIT_1 --> FIN_WAIT_2 --> TIME_WAIT --> CLOSED 

服务器 CLSOE_WAIT --> LAST_ACK --> CLOSED

3):什么是TCP半关闭(Half-close)状态。

半关闭状态发生在四次挥手的第二次挥手后,此时客户端不能发数据但是能接收服务端发来的数据,服务器处于CLOSE_WAIT状态

直到它处理数据完毕!

4: TCP握手为什么是四次,不能像握手那样三次?

因为TCP是全双工通信,所以TCP不管是建立连接,还是断开连接,本身是要求四次的,只不过在建立连接的时候,没有额外的数据包,所以第2次和第3次握手合并为一次!断开连接的时候,因为中间TCP处于半关闭的状态,客户端还要继续接收服务端没有发送完的数据,所以第2次和第3次不能合并,就是四次!

5):TIME_WAIT状态的作用是什么?

主要有两个作用:

第一个:保证双方能够正常关闭

如果没有TIME_WAIT状态的话,客户端最后一次发送ack应答报文后就进入了close阶段。如果服务端没有收到ack报文的话,就会重传FIN报文,而此时客户端已经close了,就会返回一个RST错误报文。

有了TIME_WAIT状态的话,客户端并不会着急关闭,而是等待了2MSL再关闭,这样的话就算重传的FIN报文也能正确响应,保证了服务端的正确关闭。

这里客户端重新接收到了重发的FIN报文,time_wait就会重置(也是为了重复报文的消失,不然的话ack报文可能就会到下一次连接中了),相当于可以重传多次FIN报文,直到FIN报文上限。

这里也有说不同的操作系统方案不一样,有的不会重置time_wait,个人认为还是重置比较合理一点。

第二个:防止错误接收历史报文

假设没有TIME_WAIT状态,那么在关闭连接前有个报文被延迟了。关闭后,又重新建立了相同四元组的连接,此时前一个被延迟的数据包到达了(没有到达最大生存时间),并且正好在接收窗口内,那么服务端就会错误接收,使得数据混乱。

有了TIME_WAIT状态,由于新的连接必须在前一个连接关闭 2MSL之后才能再次发起,且前一个连接的延迟报文段在 TIME_WAIT状态的 1MSL里就已经消失,因此我们可以保证前一次连接的延迟报文段不会在新的连接中出现,也就不可能被误认为是第二次连接的报文段.

6):什么是MSL?为什么客户端在发送完最后一个ACK后还需要等待2MSL?为什么是2MSL

TCP协议的运行基于一个基本的假设:互联网上的每一个IP报文都有一个生存期限。 我们将这个生存期限定义为报文段的最大生存时间(MSL)

等待2MSL是主动关闭的一端为了应对(可能出现最后的FIN或ACK丢失导致的)超时重传,而进入TIME_WAIT阶段以备超时重传。最终目的是为了正常关闭全双工的连接

因为一个报文是MSL,如果出现了ACK丢失,那么重传FIN占用一个MSL,发送ACK占用一个MSL,加起来就是2MSL。

7):如果在四次挥手过程中,最后的ACK丢失会发生什么?

服务器会重新发送FIN,客户端在TIME_WAIT期间会接收到这个重传的FIN,并重新发送ACK,确保关闭过程完成

8):TIME_WAIT状态下,如果客户端立刻重启并尝试与同一服务器建立新连接,会发生什么?

可能会遇到问题,因为TIME_WAIT期间,相同的四元组(源IP、源端口、目的IP、目的端口)不能被重新使用。客户端需要等待2MSL后才能建立新连接,或者使用不同的源端口。

  • 15
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值