How to erase values in a map with a struct? [C++]

351 views Asked by At

Im working in a small TCP client-server, and i use 'map' with a struct to store the client tracking number his ip and his socket. And the main problem is, when i want to delete his data from the 'map' (Connection closed) it does, but when it comes 2 or more clients it seems the server got lag and later, when 1 or more clients closes his connection, the server app stops responding (but accepting connections)... maybe stops in a infinite loop? Anyways... here is my code:

//------------------------------
//--------------- main.h

struct ClientData{
    int sock;
    char IP [65];
};

class ServerNetwork
{
public:
    map<int, ClientData> MapClient;
...


//------------------------------
//--------------- ServerNetwork.cpp

void ServerNetwork::SendToAll(char * packets, int totalSize)
{
    SOCKET currentSocket;
    map<int, ClientData>::iterator iter;
    int iSendResult;
    if (MapClient.empty()){
        return;
    }
    for (iter = MapClient.begin(); iter != MapClient.end(); iter++ )
    {
        int currentID = iter->first;
        currentSocket = iter->second.sock;
        iSendResult = SendInfo(currentSocket, packets, totalSize);

        if (iSendResult == SOCKET_ERROR)
        {
            closesocket(currentSocket);
            printf("Closed Connection from Client # %d\n", currentID);
            RemoveClient(currentID);
            iter = sessions.begin();
            iter++;
            break;
        }
        iter++;
    }
}

void ServerNetwork::RemoveClient(int ClientID)
{
    MapClient.erase(ClientID);
    printf("Deleted!\n");
}

MapClient holds client ID+(ClientSock&ClientIP) I'm using VisualStudio 2013.

Thanks!

1

There are 1 answers

8
Jan Petter Jetmundsen On

You should really take advantage of the fact that Map::erase returns the next iterator after the erase. So refactoring the erase into removeclient is a bad idea.

iter=MapClient.begin()
while(iter != MapClient.end()
{
   ....
   if(...)
   {       
      closesocket(currentSocket);
      printf...
      iter = MapClient.erase(iter);
      continue; //do this to avoid the iter++ below
   }
   iter++;    
}