teamtalk socket断线重连问题的查找

之前从teamtalk的核心库里面剥离出一个跨平台网络库,一开始用的好好的,可是在某些地方使用的时候总是出怪问题,有时候断线重连就一直连不上,导致应用失联,在实际使用场景中一直出问题,好不尴尬。

经过连三天的苦思冥想,调试代码看输出终于有些眉目了。

我是从以下几个方面着手解决的,特此记录一下,以备后用。

一个偶然的机会我发现这个socket在试图连接一些不存在的主机的时候,就会在CEventDispath类的while循环中卡住,输出信息如下:

AddBaseSocket fd is: 684
CEventDispatch::AddEvent fd is: 684
libpng warning: iCCP: known incorrect sRGB profile
----------------------------
AddBaseSocket fd is: 1516
CEventDispatch::AddEvent fd is: 1516
m_socketHandle is: 1516
----------------------------
AddBaseSocket fd is: 1520
CEventDispatch::AddEvent fd is: 1520
m_socketHandle is: 1520
FindBaseSocket fd is: 684
FindBaseSocket true
exception close,fd is: 684
CBaseSocket::OnClose
onClose
FindBaseSocket fd is: 1520
FindBaseSocket true
RemoveBaseSocket fd is: 1520
FindBaseSocket fd is: 684
FindBaseSocket true
exception close,fd is: 684
CBaseSocket::OnClose
onClose

上面的程序创建socket的过程就是我重连的操作产生的,从输出可以看出,一上来程序咔咔咔,连续创建3个socket,过了一会,这3个socket被while循环检测出来,要移除,可是一看输出不对呀,怎么异常的是684,怎么要移除的是1520,结果,就死锁了,684的异常一直处理不了,卡在了那里,这个可能就是我产生异常的原因吧。而且我们这个应用部署的场景都是通过交换机的双网卡系统,有时候ip不通很常见,所以连不上服务器的概率很大,(另外一种情况就是ip在,但是端口没有监听也类似,这种情况产生异常的情况稍微快点,所以不太会出现连续创建多个socket死锁的情况,但是有时会,概率小而已)。

通过以上分析最终我对程序最初如下修改:

m_socketHandle在类初始化时设为0

在重新登录的时候做一个判断,如果m_socketHandle>0说明之前已经有创建的socket,需要等他异常退出了才能再创建

void ClientSocket::_doReloginServer()
{
    if(m_socketHandle>0)return;//当前已经有一个socket了,需要等他退出才能再创建
    qDebug()<<"----------------------------";
    if(Setting::get("serverIp").isEmpty()||Setting::get("serverPort").isEmpty())return;
    m_socketHandle = imcore::IMLibCoreConnect(Setting::get("serverIp").toStdString(), Setting::get("serverPort").toInt());
    qDebug()<<"m_socketHandle is:"<<m_socketHandle;
    imcore::IMLibCoreRegisterCallback(m_socketHandle, this);
}

再onClose的地方,我把它置为0,这样下次就可以重新创建socket尝试连接服务器了

m_socketHandle=0;

总结:

经过这么一改,程序好像可以运行正常了,目前还没什么大问题,这个令人费解的问题总算告一段落了

猜你喜欢

转载自blog.csdn.net/fanhenghui/article/details/83759646