UNIX Socket FAQ

A forum for questions and answers about network programming on Linux and all other Unix-like systems

You are not logged in.

  • Index
  • » Networking
  • » another connect() select() non-blocking question

#1 2013-09-11 07:56 PM

silencecloak
Member
Registered: 2013-09-11
Posts: 3

another connect() select() non-blocking question

create socketServ as non-blocking
listen
FDSET(sockServ, &readfds)
max = socketServ

do
{
   select(max+1, &readfds, &writefds, null, 1 second)
   //process new connections
   if(FDISSET(sockServ, &readfds)
   {
      newSock = accept(...)
      if(no error)
      {
           FDSET(newSock, &writefds)
           if(newSock > max)
               max = newSock
       }
   }

   for (i=0; i < max; i++)
   {
      if(FDSET(i, &writefds)
      {
          if(i = sockServ)
          {
              continue
          }
          create thread to deal with send(data)
          FD_CLR(i, &writefds)
          close/shutdown(i)
      }
    }
} while(1)

Last edited by silencecloak (2013-09-11 07:58 PM)

Offline

#2 2013-09-12 12:59 PM

RobSeace
Administrator
From: Boston, MA
Registered: 2002-06-12
Posts: 3,839
Website

Re: another connect() select() non-blocking question

In the server code, your for() loop should be "i <= max" rather than "i < max", since "max" is actually set to the largest FD seen, so you want to include that value in the loop...

Also, I'm going to assume the "if (i = sockServ)" is just a typo in your pseudocode, and the real code uses "==" as it should?  Of course, you don't even really need to test for that, since you never add "sockServ" to the "writefds" set, so you should never see it listed as writable...

Also, why would you put a 1 second timeout on your select()?  Do you do something else every second if the select() call times out?  If not, then your best bet is a NULL timeout, so it just blocks in select() for however long needed until something is ready for you to handle on one of the FDs...  No point in senselessly burning CPU doing nothing...

In the client code, you say "my understanding is that this will be non-blocking since the listening socket is non-blocking"...  What listening socket?  There isn't one in a client, generally!  The listening socket is in the server...  So, in the server code, the new sockets it gets from accept() MIGHT inherent non-blocking mode from the listening socket...  But, even that isn't universal, and the behavior varies from system to system...  So, your best bet is always setting it to non-blocking mode manually if that's what you want...  But, in any case, it has no effect on the client's sockets!  Those will likely be blocking mode by default, if you don't explicitly set them non-blocking...  So, that non-blocking connect() code you have there probably isn't getting used at all, and likely the connect() call itself will block until success/failure...  (Which is often fine for a client, anyway...  The only real use for doing a non-blocking connect is if you wish to place a timeout on it to give up on the connect attempt sooner than TCP would normally...)

Offline

#3 2013-09-13 02:04 AM

silencecloak
Member
Registered: 2013-09-11
Posts: 3

Re: another connect() select() non-blocking question

Hi Rob,

Thanks for your reply.

I need to use a low timeout because I actually intend to do some more work than posted here at the end of the servers do while loop. After the servers for() loop, I will be checking to see if there is data to send to another (muticast) socket.

I agree with what you have to say about the connect() being blocking as opposed to non-blocking.

Offline

#4 2013-09-13 11:45 PM

silencecloak
Member
Registered: 2013-09-11
Posts: 3

Re: another connect() select() non-blocking question

//if connect fails, try again until we succeed
do
{
  ret = connect(...)
}while (ret < 0); //failed
//connect has succeeded, now lets recv some  data
recv(...)

Offline

#5 2013-09-14 02:31 PM

RobSeace
Administrator
From: Boston, MA
Registered: 2002-06-12
Posts: 3,839
Website

Re: another connect() select() non-blocking question

No, most of that code was for handling a non-blocking connect()...  If you're going to do a blocking connect, it's not necessary...

However, just retrying the connect() over and over in a loop when it fails is probably not wise, either...  If something happens with the server so that connection becomes impossible, the clients will spin forever trying to connect and never being able to...  I'd think just having the clients die if the connect() fails makes more sense, generally...  Or, perhaps retry a few times, but set some upper limit on the number of retries, at which point you just give up...  Or, at the very least, if you really need to retry forever until you succeed, then throw a sleep() or some other kind of delay in between retries, so you don't waste so much CPU retrying and failing in a tight loop...

Offline

  • Index
  • » Networking
  • » another connect() select() non-blocking question

Board footer

Powered by FluxBB