[C++] Async sockets using the plain vanilla socket API??

Started by
12 comments, last by Red Ant 18 years, 9 months ago
Hello, I have a server application which creates one thread per client it talks to. Once a connection has been initiated, the client may wish to send stuff to the server at any time, so on the server side I must constantly be ready to receive the data and react to it. If this was the only thing I'd have to do in the thread, then I suppose using a blocking socket object would be just fine. I could just recv and not worry about the thread being blocked until the client actually sends me something. Unfortunately, besides being ready to receive data from the client at all times, I must also be ready to react to events sent to my thread from ANOTHER thread in server and react to those as well, which means the idea of using blocking sockets goes straight out the window. What I envision is something like the following: Each of my threads which talk to the clients owns ONE event object. When the thread has determined that there is nothing to do at this time, it suspends itself using this event object. As soon as the client sends stuff using the connection associated with that particular thread, the event object fires (kinda like with the overlapped I/O ReadFile() function from the Windows API) and my thread wakes up. Similarily, if that other thread in my server which I mentioned before, decides that it has work for my client thread, it simply signals its event object, also causing the thread to wake up. Of course I'd need a boolean/integer that the OTHER thread sets to true so my client thread knows whether it was woken up by that OTHER thread or because the client has sent it some new data. Anyway, is there a way to set up a socket object for asynchronous operation using nothing but the normal socket API ... socket, connect, recv, send, accept and all of that? I'm reluctant to use anything Windows specific because I'd like to keep my stuff portable if possible.
Advertisement
Are you sure you need asynchronous operation? It sound like you only need non-blocking sockets. For that all you to do is call ioctlsocket() with FIONBIO.
Oh, there is a difference between non-blocking and asynchronous sockets? I was always under the impression that they were the same thing??
In the context of winsock, asynchronous usually means that you've used WSAAsyncSelect(), which sends windows messages when socket events occurs.
Ah okay. Yes, in that case I really need non-blocking sockets. I actually want to avoid Windows messages or any of that. Like I said, I need my code to be as portable as possible, so I'm trying hard to steer clear of the Windows API. Anyway, I'll have a look at ioctlsocket(), so thanks a bunch!
Hi again!

I've read up on ioctlsocket() and FIONBIO. This is what I found.

Quote:
FIONBIO
The *argp parameter is a pointer to an unsigned long value. Set *argp to a nonzero value if the nonblocking mode should be enabled, or zero if the nonblocking mode should be disabled. When a socket is created, it operates in blocking mode by default (nonblocking mode is disabled). This is consistent with BSD sockets.


Right, understood. However ...

Quote:
This ioctlsocket function performs only a subset of functions on a socket when compared to the ioctl function found in Berkeley sockets. The ioctlsocket function has no command parameter equivalent to the FIOASYNC of ioctl (emphasize mine), and SIOCATMARK is the only socket-level command that is supported by ioctlsocket.


I take that to mean even tho it is possible to set up sockets for non-blocking operation, there is no way I can have the socket send me some kind of notification when it has received something. I'd have to poll the socket to see if anything has arrived. Is that correct? If so, then I need to find another solution.
man select
I've looked at that as well, but I don't see how it would help me in the slightest. Have you read my problem description?

Oh, another thing ... assuming a blocking socket, can one thread successfully write data to the socket while another thread is doing a blocking read on the same socket? Or would that fail by definition?
I think I've found an acceptable solution to my problem. I'm still using blocking sockets. I just rolled my own asynchronous recv function, which starts a new thread that then does a blocking read and notifies the caller via an event object passed to the function as soon as the blocking read has returned.
Quote:Original post by Red Ant
I've looked at that as well, but I don't see how it would help me in the slightest. Have you read my problem description?



You don't see how abstracting the entire threaded event notification system you've developed into a single loop is helpful?

*shrug* select() is the common, portable way these things are done.

This topic is closed to new replies.

Advertisement