注意:我正在混合一些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);
}
添加客户端(每个客户端都在其自己的线程中运行)
//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;
}
服务器等待阻塞recv()调用的客户端消息
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)
你能为每个连接存储一些状态吗?就像最后一次收到东西一样?
然后,您可以定期循环活动连接并修剪任何长时间没有发送任何内容的连接,因为连接可能更加陈旧。