2011-12-18 44 views
0

注意:我混合了一些C++,但它不應該太混亂。如果通過代理連接,客戶端不會斷開連接

連接的客戶端被添加到一個multimap(可能aswe是一張地圖,我知道^^)。

的多重映射

typedef std::multimap<std::string, SOCKET> clientMap; 
typedef std::pair<clientMap::iterator, 
        clientMap::iterator> 
            clientIters; 
clientMap clientmap; 
clientIters clientByID(std::string clientID) 
{ 
    return clientmap.equal_range(clientID); 
} 

添加客戶端(每個客戶在自己的線程中運行),用於與阻塞的recv客戶端的消息

//Add clientID to map of clients 
if(clientAdded == false) 
{ 
    std::stringstream ss; 
    ss << lpParam; //Use socket# as the unique ID 
    clientID = ss.str(); 
    clientmap.insert(std::pair<std::string,SOCKET>(clientID,sock)); 
    clientAdded = true; 
} 
//Client wasn't added correctly! 
if(clientID == "" || clientAdded == false) 
{ 
    std::cout << "Problem adding client" << std::endl; 
} 

服務器等待()調用

ret = recv(sock, szBuff, DEFAULT_BUFFER, 0); 
if (ret == 0)  // Graceful close 
    break; 
else if (ret == SOCKET_ERROR) 
{ 
    printf("recv() failed: %d\n", WSAGetLastError()); 
    removeUser(clientID); 
    break; 
} 

removeUser()函數

void removeUser(std::string clientID) 
{ 
    std::cout << "Going to try and remove client: " << clientID << std::endl; 

    //Remove client 
    clientIters iters = clientByID(clientID); 
    clientMap::iterator it = iters.first; 
    while(it != iters.second) 
    { 
     clientmap.erase(it++); 
     std::cout << "removed client: " << it->first << std::endl; 
    } 

    //Show remaining clients 
    std::cout << "clients left:" << std::endl; 
    for (clientMap::iterator it = clientmap.begin(); it != clientmap.end(); ++it) 
    { 
     std::cout << it->first << std::endl; 
    } 
} 

所有這一切,如果我關閉了連接到任何我的本地IP或外部IP(直接)的客戶端工作正常。

recv() failed: 10054 
Going to try and remove client 0000008C 
removed client 0000008C 
clients left: 
00000084 
00000088 

但如果我把插圖中(使用proxifier)代理,服務器認爲連接仍處於活動狀態或東西,因爲服務器沒有做任何事情我關閉客戶端。它只是坐在那裏......等着什麼。

我使用this socket class作爲基礎,但現在已經進行了相當多的修改。

我怎樣才能確保一個封閉的客戶端肯定是從多圖中刪除?

+0

我的猜測是代理軟件可能仍然保持連接開放到您的服務器? –

+0

@Luke根據Proxifier,連接已關閉。 – natli

+0

您對'recv()'的調用是否無限期阻止? –

回答

0

你能存儲每個連接的狀態嗎?就像最後一次收到東西一樣?

然後,您可以定期循環訪問活動連接,並修剪任何長時間未發送任何內容的連接,因爲連接可能過時。

+0

這會安全嗎?我使用multimap一次性向所有連接的客戶端廣播消息,如果它試圖向未真正連接的客戶端發送消息,是不是很危險?會發生什麼? – natli

+0

我真的不知道,你必須嘗試一下,看看。我猜想發送消息給客戶,這不是真的不應該有問題... –

相關問題