tcp 要如何联调好呢?

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

至于抓包,小概率时间抓包不现实
gimp
2020-05-23 23:50:22 +08:00
定位问题可以用 Wireshark 抓包。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/674727

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX