2011-12-18 13 views
0

注:C & C++をいくつか混在させていますが、あまり混乱させるべきではありません。クライアントがプロキシ経由で接続されている場合に切断されない

接続されたクライアントがマルチマップに追加されています(地図として使用されている可能性があります^^)。

マルチマップ

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

@ルーキーProxifierによると、接続が閉じられました。 – natli

+0

'recv()'の呼び出しは無期限にブロックされますか? –

答えて

0

接続ごとにいくつかの状態を保存できますか?何かが最後に受け取られた時のように?

アクティブな接続を定期的にループして、何も送信していないものをプルーニングして、接続が古くなってしまう可能性があります。

+0

これは安全でしょうか?マルチマップを使って、一度にすべての接続されたクライアントにメッセージをブロードキャストします。実際に接続されていないクライアントにメッセージを送信しようとすると危険ではありませんか?何が起こるでしょうか? – natli

+0

私は正直に分かりません、あなたはそれを試してみる必要があるでしょう。私は実際には問題ではないはずのクライアントにメッセージを送信すると思います... –

関連する問題