怎么进行TCP异常关闭的问题分析

发布时间:2021-12-28 16:28:16 作者:柒染
来源:亿速云 阅读:162

本篇文章为大家展示了怎么进行TCP异常关闭的问题分析,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。

研究测试TCP断开和异常的各种情况,以便于分析网络应用(比如tconnd)断网的原因和场景,帮组分析和定位连接异常掉线的问题,并提供给TCP相关的开发测试人员作为参考。

各个游戏接入都存在一定的掉线问题,而且有的游戏项目的掉线比例还比较高,现在互娱自研游戏的网络接入基本上都用的是tconnd和ProtocalHandler组件,因此参与其掉线原因分析和研究。

在参与A项目的掉线问题研究分析过程中,tconnd增加了玩家每个连接的流水日志和ProtocalHandler增加了每个连接的Qos上报日志,通过这些日志记录了每一次连接的断开原因和相关统计数据,其中包括了连接异常断开时TCP的底层错误码。

通过对tconnd的流水日志和ProtocalHandler的Qos日志进行统计分析,发现连接异常断开时TCP的错误码大部分是“104: Connection reset by peer”(Linux下)或“10054: An existing connection was forcibly closed by the remote host”(Windows下),单纯从错误码本来来说,大家都明白是“网络被对端重置了”,但究竟什么情况下会导致这种情况呢?因此就对TCP的各种关闭情况做了进一步的测试研究。

一. TCP异常关闭的研究测试

1. 服务器端只Recv消息而不Send消息

1.1 测试方法

服务器程序在接受客户端的TCP连接后Sleep几秒钟,客户端程序在TCP连接后立即发送很多消息给对端后做相应动作(退出或等待),服务器程序Sleep完后开始Recv消息。

注意:服务器程序测试了Linux和Windows版本,但客户端只测试了Windows版本,如果是Linux客户端则有些Case的结果会不一样。

1.2 测试Case

2.服务器端Recv消息并Send应答消息

2.1 测试方法

服务器程序在接受客户端的TCP连接后Sleep几秒钟,客户端程序在TCP连接后立即发送很多消息给对端后做相应动作(退出或等待),服务器程序Sleep完后开始Recv和Send消息。

注意:服务器程序测试了Linux和Windows版本,但客户端只测试了Windows版本,如果是Linux客户端则有些Case的结果可能会不一样。

2.2 测试结果

3. 效果和总结

3.1 总结

TCP发现网络异常(特别是Linux下的104错误或Windows下10054错误)的情况很多,比如网络本身的问题、中间路由器问题、网卡驱动器问题等不可抗拒因素,但下面是应用程序本身可能会导致的问题,也是我们需要进一步研究和解决的情况,特别是程序崩溃导致问题:

3.2 效果

针对A项目的掉线问题,通过问卷调查和联系个别玩家等方法,发现掉线的情况很大部分是客户端程序直接退出了,因此推动项目组实现了客户端的Qos上报功能,最后通过客户端的Qos上报的统计数据得出客户端程序的崩溃比例比较高,占了总掉线的很大比率,当然其它情况也存在,但比例相对比较小。

因此,A项目首先应该解决客户端程序的崩溃问题,如果该问题解决了,也就解决大部分掉线问题。

二. TCP异常关闭的进一步研究测试

1. 背景

B项目游戏在跨服跳转时的掉线比例比较高,经过分析ProtocalHandler和tconnd的日志,发现掉线出现的情况是:tconnd发送了跨服跳转消息后立即关闭了Socket,客户端进程在接收到跨服跳转消息之前发送消息后收到Windows 10054错误,然后做断线重连失败。

B项目实现跨服跳转的流程是GameSvr给客户端程序下发的跨服跳转命令的同时携带了Stop请求,也就是说tconnd在向客户端转发跨服跳转消息后立即就会关闭当前的Socket连接,而且B项目的客户端程序会定期不断地向服务器上报消息。这又怎么会导致客户端程序收到10054错误而呢?鉴于此,对TCP的连接做进一步的场景测试分析。

2. TCP异常进一步测试研究

2.1 测试方法

客户端和服务器端程序建立TCP连接,服务器程序在TCP缓冲区中有消息或没有消息的情况下关闭Socket,客户端在对端Socket已经关闭的情况下继续Send和Recv消息。

注意:服务器端只测试了Linux版本,但客户端测试了Windows和Linux两个版本。

2.2 测试结果

3 效果和总结

3.1 总结

TCP应用程序某些看是正常的行为下也可能会导致对端接收到异常,比如当TCP接收缓冲区中还有未收数据的情况下关闭Socket,则会导致对端接收到异常关闭而不是正常关闭;反过来说,当TCP检测到异常关闭时并不一定表示业务上出问题了,因为很可能就是业务正常结束了。下面是本次测试的主要结论:

3.2 效果

B项目跨服跳转的掉线问题有相当一部分的种情况是tconnd向客户端转发跨服跳转消息后立即关闭Socket连接,而此时刚好客户端向tconnd发送了数据包:

最后,与B项目项目组一起讨论,改进了大部分跨服跳转的业务流程后,掉线比例j减少了很多,当然还是存在一定比例的掉线,但这应该就是其它一些原因了(网络异常问题原因很多,国内当前的网络环境下,掉线问题是不可能完全避免的)。

通常情况下,向TCP的Socket发送完数据后关闭Socket,大家认为这样很正常的方式肯定没有问题,对端应该正确收完数据后收到TCP的关闭消息,但实际上在某些情况下并非如此:当TCP本端的接收缓冲区中有未收的数据时关闭Socket,这会导致对端收到RST的异常关闭消息;当对端在本端已经关闭Socket的情况下再次发送消息时,也会导致对端收到异常关闭消息;还有为了避免TIME_WAIT而设置了SO_LINGER选项的话,也会导致连接提前夭折使对端收到RST异常关闭消息。

有些时候业务流程对是否引起掉线也很重要(特别是连接关闭流程),比如前面的B项目的跨服跳转掉线问题很大部分就是因为GameSvr请求关闭连接导致的。建议各个游戏项目的关闭流程(包括跨服跳转的原连接的关闭)最好都由客户端发起关闭,这样就一定程度上避免上述问题的发生(因为客服端发起关闭的时候,一般业务流程都走完了,服务器端也不会再向客户端发送消息了)。

程序收到网络异常的情况很多(最多的就是Linux下的104错误和Windos下的10054/10053错误):有网络本身的问题、也有应用使用不当的问题;有运营商之间的跨网络问题、网络中间路由器问题、玩家机器硬件(比如网卡及其驱动)问题和操作系统、杀毒软件、防火墙等软件问题,还有玩家的上网设备和路由器等中间设备问题等,但客户端程序崩溃问题有可能会占掉线的很高比例,这也是值得我们注意和改进的地方。还有种情况值得我们注意,有些TP-LINK的路由器,当UDP包大小超过其MTU值时会导致用户机器的网络断开,从而引起掉线(这个问题在某些项目的个别玩家中已经出现过)。

网络异常关闭引起掉线是当前游戏中普遍存在的问题,区别只在于掉线的比例多少,特别是国内各运营商之间跨网络访问更是不太顺畅,要将其完全消除是不可能的,但我们的目标是将其控制在较小的可接受范围内。

上述内容就是怎么进行TCP异常关闭的问题分析,你们学到知识或技能了吗?如果还想学到更多技能或者丰富自己的知识储备,欢迎关注亿速云行业资讯频道。

推荐阅读:
  1. 如何进行DOS换行符的问题分析
  2. 怎么进行TCP可靠传输的实现

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

tcp

上一篇:如何进行ReactNative For Android 框架启动核心路径剖析

下一篇:如何实现Linux 2.6.16 TCP连接速度异常的问题分析

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》