1. 程式人生 > >teamtalk socket斷線重連問題的查詢

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;

總結:

經過這麼一改,程式好像可以執行正常了,目前還沒什麼大問題,這個令人費解的問題總算告一段落了