1
mhycy 2020-05-23 18:47:32 +08:00
协议设计有问题,是否正确收到消息需要正确设计 ACK 机制,不能把数据传到了缓冲区就写入日志说是成功发送
( TCP 底下的 send 操作全都是到达缓冲区) |
2
SelectLanguage OP @mhycy 什么是正确的 ACK 机制 能否举个例子
|
3
zexinwu84 2020-05-23 19:29:02 +08:00 via Android
在自己的应用层,实现收到确认的定义
|
4
SelectLanguage OP @zexinwu84 那收到确认的定义 如果没收到呢。。。。还是在纠结某到消息到底送达没
|
5
linvon 2020-05-23 20:36:41 +08:00 via iPhone
那就抓包呗
|
6
hercule 2020-05-23 23:23:03 +08:00 2
我说说我的想法,不一定是正确的,只是提供一个参考,如果有不对的地方,麻烦指正。
首先,就像一楼同志说的那样,如果记录的日志是在应用层调用 send 后,就记录,其实这个 send 只是把数据放入了发送缓存区,是操作系统再发送出去,所以,记录日志成功,不代表就已经真正发送成功了。 TCP 是可靠传输,按照一般来说,只要双方的连接没出现问题,就应该收到数据,即使出现丢包的问题,也会重传。linux 系统有个 tcp_retries2 变量设置了重传次数,重传时间间隔是指数级退避,直到达到 120s 为止,默认重传次数是 15 次,总时间将近 15 分钟,你可以比较一下日志当中这个连接是否出现了这么多次重传,如果出现了这么多次重传,那么说明,服务端应该是没问题,应该是客户端死机等等情况,造成不能正常接收。 发送缓存区的数据什么时候丢失,有种情况,就是收到对方的 RST 的时候,立马释放资源,丢掉了发送缓存区的数据。比如:当客户端出现状况,重启,就丢失了这条连接,但是服务端并不知道这种情况,还是发送数据给客户端,因为对客户端来说,这条连接已经不存在,当收到数据的时候,就会回复一个 RST 报文,这个时候,服务端就立马释放资源。 |
7
turi 2020-05-23 23:27:00 +08:00
6 楼说的不错,只要连接不断开,发送给操作系统的缓存数据,最终都会到达另一端。
至于抓包,小概率时间抓包不现实 |
8
gimp 2020-05-23 23:50:22 +08:00
定位问题可以用 Wireshark 抓包。
|