Sign in to follow this  

How to delete Inactive Client

This topic is 3288 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, i've a STL::MAP with all client connected to my server. And i've a sub-structure called "ClientGroup" (a Room where all player can chat). I need to delete inactive client. For example, when a client crash, i can't read a disconnect message from him, so i need to delete it when he is gone. I've tried to create a method like this:
void SystemServer::sendMessageControlToAllClient()
{
	map<SOCKET, Client*>::iterator itl;
	string	buf = "a";
	bool	cicla = true;
	int iStat;
	string tempNickname;

	while(cicla)
	{
		for(itl = CServerObj.ClientMap.begin(); itl != CServerObj.ClientMap.end(); ++itl)
		{
			cicla = false;
			iStat = send((*itl).first, buf.c_str(),buf.size(), 0);

			if(iStat == -1)
			{
				Client *client = CServerObj.ClientMap[(*itl).first];
				if(client->getGroup() == NULL)
				{
					CServerObj.removeClientFromMap((*itl).first);
					CServerObj.m_numClient--;
				}
				else
				{
					tempNickname = client->getGroup()->getNickNameFromGroup((*itl).first);
					client->getGroup()->removeClient(client->getGroup()->getNickNameFromGroup((*itl).first));
					//client->getGroup()->deleteInactiveClient();
					CServerObj.removeClientFromMap((*itl).first, tempNickname);
					CServerObj.m_numClientConnectedToAGroup--;
					CServerObj.m_numClient--;
				}
				cicla = true;
				break;
				
			}
		}
		if(CServerObj.ClientMap.size() == 0)
			cicla = false;
	}
	

}
but this method is really expensive. I want create e "Timer" for each client connected, when a timer is finished, i delete this client. Anyone have another idea or another tecnique to solve this problem? Thanks a lot and sorry for my bad english!

Share this post


Link to post
Share on other sites
I found a solution! I send always a message to all client when he chat. So i can use che send() method to see if the client respond. So i can do like this:


iStat = send((*itl).first, buf.c_str(),buf.size(), 0);


iStat is an Int. So if iStat = -1 i can catch the Error with WSAGetLastError ( http://msdn.microsoft.com/en-us/library/ms740149(VS.85).aspx ). So now i try this solution, but i need suggest anyway =).

Thanks!

Share this post


Link to post
Share on other sites
1° Require all clients to send you a message every 10 seconds [or whatever amount of time you wish]. If the user types nothing, just send an empty "I'm still here" message.

2° Whenever you receive a message from a client, store the time.

3° When you want to clean up disconnections, check the "last received message" time of every client and, if it's older than 10 seconds, disconnect the client.

Share this post


Link to post
Share on other sites
Are you using select() to see which sockets have something to read from?

If so, finding out when a client has disconnected is pretty easy (when TCP/IP is used).

while (running)
{
select(...);

for (all sockets)
{
if (FD_ISSET(socket, ...))
{
bytes_received = recv(socket, ...);

if (bytes_received < 0) { /* hard disconnect */ }
else if (bytes_received == 0) { /* graceful disconnect */ }
else if (bytes_received > 0) { /* received some data from this socket */ }
}
}
}


You can also use select to check which sockets have errors (exceptions) on them, which might also be a good idea.

I use the above and it seems to work pretty well.

The only problem that I know of is when a client doesn't communicate for a long time, the underlying TCP connection seems to silently time out and the server doesn't realize the client has disconnected. This can probably be solved by checking sockets for exceptions using the select statement (I don't do that yet), or by sending keep-alive TCP packets every minute or so (at least). Other than that, it's flawless.

Share this post


Link to post
Share on other sites
To time out idle clients, you should store the client pointers sorted by last time data received, in a priority queue or map of some sort. That way, you don't have to scan through all clients to find the clients that are old; you can scan from the oldest, and stop as soon as you find one that's not old enough to disconnect.

Share this post


Link to post
Share on other sites
Thanks for suggests, but i've another question: I'm using a blocking socket and i've a thread to listen socket recv(). So when the connection with a peer goes down, i recive always a "-1" (and i use WSAGetLastError() to see this error). So, i catch the "-1" and i shutdown the connection and delete the client from my clientMap. Without using a timeout. So, i need to know what are the disadvantages in this tecnique.

thanks.

Share this post


Link to post
Share on other sites
Quote:
Original post by Tano_ITA
So when the connection with a peer goes down, i recive always a "-1" (and i use WSAGetLastError() to see this error).
One cannot distinguish between a disconnected client and a client with a slow connection. Someone has to decide that clients that take longer than X to respond are seen as disconnected: if you don't, then someone else has for you—which means you might not know what X is.

  • Client A is connected to your server. All of a sudden, his router is clogged and any message you send him takes one entire minute to go through and reach him (but the messages are still received).
  • Client B is also connected to your server. All of a sudden, his router crashes and doesn't forward messages to him anymore (so he's disconnected).


Your computer sends a message to both clients. After one minute, it still hasn't received a response from either A or B, which means it does not know who is who. Does it keep both clients as "connected" or does it disconnect both?

Share this post


Link to post
Share on other sites
Maybe for your purposes, select does the deal, but, and here is my opinion, I think is better you use IOCP.

A little metaphor:

You could use a bazzuca to kill a fly, and also an elephant, but you can't kill an elephant with rolled paper.

That's only me, most people think different.

Share this post


Link to post
Share on other sites
Thanks, i wanna try to study IOCP. But i need some book or some link to learn about this tecnique. So Have you any link for those IOCP?


Thanks a lot, i begin to learn to use a Bazooka! :D

[Edited by - Tano_ITA on December 11, 2008 4:46:02 AM]

Share this post


Link to post
Share on other sites
In codeproject, there are some articles about iocp, take a look here and here, and type iocp in the search box to find more.
I also recommend you to take a look in this article, and this article. And also some other articles about IOCP, google it, MSDN will help to.

And keep always coding, try, and try again, and you will make it, is not that hard as it sounds.

Share this post


Link to post
Share on other sites

This topic is 3288 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this