TCP accept non-blocking

Started by
4 comments, last by Woltan 15 years, 8 months ago
Hey guys, I have a problem concerning the accept socket function. Maybe one or two could gimme a hand out of my dilemma. Here is my situation: I have to accept recv and send stuff in a single thread, and do not have access to any window callback function. To do this, I used the select function in combination with the FD_SET etc. macros.

static SOCKET sListen, sClients[8];
//... Init socket and wsa stuff

while(1)
{
FD_SET(sListen, &fdset);
if(select(0, &fdset, NULL, NULL, &timeval) > 0)
{
    accept(...);
}

for(int i = 0; i < 8; i++)
{
FD_SET(sClients, &fdset);
if(select(0, &fdset, NULL, NULL, &timeval) > 0)
{
    recv(...);
}
}

}

This seemed to be working just fine, unter I closed my client before I shut down my server. What it did: My server was expecting a connection attempt, because the sListen socket had stuff to be read. But since this is not the case, I am stuck in the accept() function and my whole program stops right there! Does any of you have an idea how I could solve this problem? As said before: I cannot open another thread and do not have access to a window callback function. Thx in advance for any hint/link/suggestion/tipp/ANYTHING! ;) Regards Woltan
Advertisement
Did you try setting the socket to non blocking by calling ioctlsocket() with a FIONBIO argument?
The whole point of select() is that, if it returns true, then you are GUARANTEED to not block on the next call to that socket.

However, I see a few problems with that code:

1) You're not clearing the socket set before you FD_SET the socket identifiers in it. This means that old bits may still be set. This is probably the cause of the bug you're seeing.

2) Your loop setting the client sockets calls select() once per socket. That's quite wasteful. It's better to loop through the sockets, set all the identifiers, call select() once, and then loop over the result, calling recv() on each socket that is returned in the fd_set.

3) Passing 0 for the first argument to select() works for Windows, but fails big on UNIX.
enum Bool { True, False, FileNotFound };
in sdlnet
newConnection = NULL;if (newConnection = SDLNet_TCP_Accept(ListenSocket)){  //Do things}


has worked just fine for me, no blocking.
Hey folks,
thank you very much for your input! I very much hope that this will solve the problem, and I am will give it a shot on monday. For the weekend, I'll try to get it of my mind as much as possible ;)

I'll probably have to get back to you on monday, with other problems that come up then ;)


Cherio and thx again for your help
Regards
Woltan
Hey folks,
I just wanted to add the quick note, that the ioctlsocket function did the trick! Futhermore, I changed the FD_SET things according to the suggestion of hplus0603.
This community is the best!!!
best regards (with hopes that i maybe once give some advice in return myself)
Woltan

This topic is closed to new replies.

Advertisement