Valhalla Legends Forums Archive | C/C++ Programming | Need help with auto-reconnection problem - not detecting disc

AuthorMessageTime
warz
Currently I have a method implemented that I thought should work. I guess the problem is that the bot is having trouble detecting if it has been disconnected or timed out from battle.net. I'll paste some code, because I think it's a relatively simple fix and that the code itself probably explains everything. Here is some extreme psuedo code...

[code]
unsigned __stdcall botMain(void *threadname) {
...

// Setting up socket and connecting to bnet here...

global->packetManip.connected = true;

while(global->packetManip.connected == true) {
recvlen = recv(global->packetManip.Buff.sock, (char*)buffer + buflen, 1024, 0);
if(recvlen == 0 || recvlen == SOCKET_ERROR || recvlen == WSAETIMEDOUT) {
if(recvlen == SOCKET_ERROR)
global->logManip.logOutput(LOG_CONN_ERROR, true, "Socket error!\n");
global->logManip.logOutput(LOG_CONN_ERROR, true, "Connection closed!\n");
global->packetManip.connected = false;
break;
}
...
}

// If the connected loop exits, the bot has been disconnected and my thread is closed
}

int main() {
global->connected = false;
do {
  // here I setup and begin my threads where inside connected is set to true upon connected
  // and false if it is disconnected
} while(global->connected == false);
}
[/code]

Now, when the bot times out, apparantly it's not able to determine if it has or not, so the connect variable is always true.

Is this an efficient method of handling this? It doesn't work. What's another way of handling this?
April 28, 2006, 4:45 AM
rabbit
recv errors aren't the only ones you should check for.  Check for send errors too, especially on SID_NULL, and SID_PING (if you don't want to catch EVERY packet).
April 28, 2006, 11:45 PM
tA-Kane
Especially make sure to have a no-data timeout: a lot of times, TCP won't detect the disconnect until you actually try to send at least one byte... and rarely, it won't even detect it then. Plus, I consider it to be good habit.
May 1, 2006, 3:58 AM
warz
How do I make a no-data timeout? That's what my problem is.
May 1, 2006, 6:20 AM
tA-Kane
Under the Windows environment, I highly recommend the use of SetTimer and friends.

If SetTimer looks too complicated, or you want to go for portability, then you could add a simple call to stdlib's time() function every time you receive something. Then, every iteration through your main loop, you call it again and compare the difference (which will be in seconds, btw).

Make sure you're confident that the other side will always send something within those seconds, though... or else you could end up thinking the connection is dead, even though it's really alive. In Battle.net's case, I do believe it sends NULL messages every X seconds of inactivity.
May 1, 2006, 6:29 AM

Search