我正在处理客户端和服务器项目。
所有会话的std :: map看起来有点像这样:
std::map<int, SOCKET> Sessions;
int g_TotalClientCount;
void Server::HandleNewClientConnection(SOCKET clientSocket){
Sessions.insert(pair<int, SOCKET>(g_TotalClientCount, clientSocket));
g_TotalClientCount++;
}
/*Something similar on disconnect*/
void Server::KickClient(int clientId){
SendPacket(...)
Sessions.erase(clientId);
}
让我们说随着时间的推移,g_TotalClientCount变得非常高并最终超过MAX_INT(最终导致错误/崩溃)。
是否有正确的方法可以在地图中删除和插入项目,还可以将g_TotalClientCount保持为实际连接的用户数而不是连接的用户数? 使用
g_TotalClientCount--;
最终会造成重复。
g_TotalClientCount仅用于HandleNewClientConnection部分。
我知道我可能永远不会有这个问题,但我想知道这样做的正确方法。
答案 0 :(得分:0)
更适合您的问题的是std::set
(对数复杂度)或更好,std::unordered_set
(恒定时间复杂度)。您可以使用iterator
方法返回的insert
作为clientId
:
C ++ 98:
#include <set>
std::set<SOCKET> Sessions;
std::set<SOCKET>::iterator Server::HandleNewClientConnection(SOCKET clientSocket) {
std::pair<std::unordered_set<SOCKET>::iterator, bool> inserted =
Sessions.insert(clientSocket);
if (!inserted.second) {
// handle the insertion error
}
return inserted.first;
}
void Server::KickClient(std::set<SOCKET>::iterator clientId){
SendPacket(...)
Sessions.erase(clientId);
}
C ++ 11 +:
#include <unordered_set>
std::unordered_set<SOCKET> Sessions;
auto Server::HandleNewClientConnection(SOCKET clientSocket) {
auto inserted = Sessions.insert(clientSocket);
if (!inserted.second) {
// handle the insertion error
}
return inserted.first;
}
void Server::KickClient(std::unordered_set<SOCKET>::iterator clientId){
SendPacket(...)
Sessions.erase(clientId);
}
C ++ 17:
#include <unordered_set>
std::unordered_set<SOCKET> Sessions;
auto Server::HandleNewClientConnection(SOCKET clientSocket) {
auto [iterator, success] = Sessions.insert(clientSocket);
if (!success) {
// handle the insertion error
}
return iterator;
}
void Server::KickClient(std::unordered_set<SOCKET>::iterator clientId){
SendPacket(...)
Sessions.erase(clientId);
}