使用 TCP socket 进行网络编程,Linux 内核会给每个 socket 都分配一个发送缓冲区和一个接收缓冲区
当发送数据时,进程会调用 send(data)/write(data) 将数据拷贝到 Linux 内核发送缓冲区,函数返回并不表示已经将数据从网卡发出了,至于什么时候发,发多少,这都是由 Linux 内核决定的
问题来了,如下场景就会发生丢包现象
- 开启 TCP「保活」机制的客户端在发送一段数据后直接关闭连接
- Linux 内核在发送数据期间网络异常,只发送了部分过去
- 重传剩余数据期间,网络仍旧异常
如何解决?需在应用层设计「确认应答」机制,依旧是上述示例,客户端不要完全依赖 TCP 协议的可靠性,调用 send(data)/write(data) 后不要傻傻以为数据一定能一字节不差地到达服务端,可以通过调用 recv(业务 ACK)/read(业务 ACK) 确认好后再关闭连接