注意:不仅 TCP 存在粘包问题,其他面向字节流的机制也存在粘包问题。
那么如何避免粘包问题呢?归根结底就是一句话,明确两个包之间的边界。
对于定长的包,保证每次都按固定大小读取即可;
对于变长的包,可以在包头的位置,约定一个包总长度的字段,从而就知道了包的结束位置;
对于变长的包,还可以在包和包之间使用明确的分隔符(应用层协议,是程序猿自己来定的,只要保证分隔符不和正文冲突即可);
TCP 报头中不是有说明数据长度的字段么 ?
思考:对于UDP协议来说,是否也存在 “粘包问题” 呢?
进程终止:进程终止会释放文件描述符,仍然可以发送FIN。和正常关闭没有什么区别。
因为 建立的 TCP 连接,是通过 Socket 建立的,Socket 本质上是进程打开的一个文件,文件就存在于 进程的 PCB 里面的一个文件描述符表,直接杀死进程,PCB 也就没了,此处的 文件相当于自动关闭了,这个过程其实和 手动调用 socket.close() 一样,都会触发 四次挥手。
机器关机/重启:和进程终止的情况相同。因为机器关机 / 重启,会杀死所有的进程。
机器掉电/网线断开:
操作系统没有任何反应时间,更不会有任何处理措施。
接收端认为连接还在,一旦接收端有写入操作,接收端发现连接已经不在了,就会进行reset。
即使没有写入操作,TCP自己也内置了一个保活定时器,会定期询问对方是否还在。如果对方不在,也会把连接释放。
另外,应用层的某些协议,也有一些这样的检测机制。例如HTTP长连接中,也会定期检测对方的状态。例如QQ,在QQ断线之后,也会定期尝试重新连接。
好啦! 以上就是对 TCP 粘包问题 以及 异常处理的讲解,希望能帮到你 !
评论区欢迎指正 !