🔍 开发者资源导航 🔍 |
---|
🏷️ 博客主页: 个人主页 |
📚 专栏订阅: JavaEE全栈专栏 |
本系列往期内容~
TCP/UDP协议深度解析(一):UDP特性与TCP确认应答以及重传机制
TCP/UDP协议深度解析(二):TCP连接管理全解,三次握手四次挥手的完整流程
TCP/UDP协议深度解析(三):TCP流量控制的魔法—滑动窗口、拥塞控制与ACK的智慧
一、 粘包问题
因为TCP协议是面向字节流的,因此接收方收到的数据是一段连续的数据,接收方无法判断那一段数据是一个整体,这一段连续的数据就像是“粘”在了一起,无法区分,而这就称之为“粘包问题”。
1.1 解决方法
该问题在传输层层面无解,想要解决这个问题需要站在应用层角度来解决。
1.约定包与包之间的分隔符
约定某一个字符作为该段数据的结束标志,例如使用换行符'\n'。
2.约定包的长度或格式
例如:约定包的前n个字节表示数据的长度 。
解决粘包问题是在自定义应用层格式的时候要考虑的问题,但是已经存在成熟的解决方案,例如:json、protobuf等,因此不必过多操心该问题。
二、TCP连接时的异常情况处理
2.1 进程崩溃
四次挥手的进行并不依赖进程,因此如果某个进程崩溃,它和正常退出没有本质区别,并不会出现异常情况。
2.2 主机关机
正常的关机都会先杀死用户的进程,但是关机也需要一定的时间,如果这段时间内挥手结束,那么就和正常一样,如果这段时间没有挥完也是可以将连接释放掉的。
2.3 接收方掉电
如果接收方掉电,发送方发送的信息将不会再收到ack,此时无论多少次的超时重传都无法解决问题,当达到一定次数后,发送方会主动发送一个“复位报文”,重置TCP连接,如果还是收不到ack,那么发送方就会主动释放掉连接。
2.4 发送方掉电
如果发送方突然掉电了,接收方因为是被动的一方,无法确认对方现在是休息了还是挂掉了,因此他只能等待下去,但是并不会无限等待,超过一定的时间后会主动的发送“心跳包”,来确认对方的状况。
心跳包并不包含载荷,他只是为了触发对方的ack,如果没有心跳就认为对方挂掉了,进行RST复位,再不行就会释放掉该连接。