Noobish non-blocking question

Started by
2 comments, last by Haytil 17 years, 9 months ago
Okay, well I'm currently trying to get my small client up and running... but I have problems due to my poor knowledge with winsock. I'm trying to figure out which would be easiest to port over to other OS's in later releases, and I figured I should try blocking sockets, but treating them non-blockingly (i.e. with select() and minimal timeval). So, with the knowledge I've learned from a couple tutorials I tried doing this:

      switch(select(1, &socket_check, NULL, NULL, &_time))
      {
         case FD_READ:
            break;

         case FD_WRITE:
            break;

         case FD_CLOSE:
            break;
      }

Well, that obviously didn't work out. I was confused why, and realized I was supposed to be using asynchronous, which of course is only available on Win32 projects. Well, wanting to port this over later, that's not a very likely option for me. So my question goes out to you, what would be the best way to make this easy to port over later? Should I stick with select (if so, how do I use it properly?), or should I just make my sockets completely non-blocking, and if so how should I handle them? I'm terribly sorry for these noobish questions, but I'm utterly confused here. Basically all I need here is a little guidance, and if possible (I'd really appreciate it), where I should head to learn (yes, I want to do the work) about the option you recommend. I already read in the FAQ that for porting to Linux, me making non-blocking sockets combined with select would be best, but also what about Mac OSX? Either way, I appreciate you taking the time to read this. :)
Advertisement
If you want highly portable socket code you should use the ACE toolkit.
The socket classes are pretty easy to get started with, though the more advanced concepts can be difficult to understand at first. There are a few books on it though.
- The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara
ACE is engineered for enterprise software like object brokers, not generally for games. It is also too large and heavy-weight for many game applications. I cannot recommend it (and thus, it's not part of the fine list of libraries found in the Forum FAQ).

The problem you're having is that you're confusing the output of select(). select() returs the number of sockets that are ready. You then go through the fd_sets you pass in, to see which sockets are actually ready, and service them as necessary.
enum Bool { True, False, FileNotFound };
First, I suggest using non-blocking sockets. Don't do blocking with time intervals, that will just confuse you later. There's no reason not to just use non-blocking sockets.

Secondly, if you're programming for Windows, make sure that before you use select() that you set the socket to non-blocking. The syntax for this is different for Windows than other OS's: You'll want to use ioctlsocket() function (look it up).

Thirdly, you're using select() wrong.

Here's how to do it for clients (look for a better explanation here):

First, make the socket non-blocking. Then, call connect(). Since it's non-blocking, you might not immediately connect, but the program won't stall. It should return SOCKET_ERROR, but WSAGetLastError() will return WSAEWOULDBLOCK, which is what you expect, so all is good.

Later, when you want to see if you've connected yet, add your socket into an fd_set, using the FD_SET macro (this is explained in the link above), and call select(), with this fd_set being the third parameter (you are interested in seeing if this socket can write - if it can, it is because it is connected). Then check the fd_set with the FD_ISSET macro. If the socket is still in the set, then you are connected.

From then on, just call select() with an fd_set containing your socket in the 2nd parameter (since you are interested in reading) when you want to see if you've gotten any data and can call recv(). And you can send() normally.

Check out the link, avoid asynchronous sockets, and good luck (I tried async sockets - its harder, more complicated, and a headache that's not worth it).

-Gauvir_Mucca

This topic is closed to new replies.

Advertisement