No navigation frame on the left?  Click here.

Sockets, IOCPs, AcceptEx

Two days ago, I took at look at the Platform SDK -- at the samples directory, to be more precise, and at the provided Winsock/completion-port sample to be quite exact. I was, mildly put, extremely unhappy with that sample; it manages to hide the important points from everyone who doesn't know already about them (and even such a person has to look around a bit to find the relevant stuff).

If I may say so myself, the small demonstration project below is superior in both readability and practical applicability. It demonstrates a small server that:

uses sockets in overlapped mode, attached to an I/O completion port (IOCP);
uses AcceptEx() to route new connections through the IOCP;
uses GetQueuedCompletionPacket() to retrieve the results of asynchronous (overlapped) I/O requests;
uses PostQueuedCompletionStatus() to send special notifications to the worker threads servicing the IOCP;
uses TransmitFile() like an FTP server might;
and demonstrates a simple state machine implementing an interactive server, which accepts commands and returns meaningful results. Simple echo servers, bah.

Do you want a blow-by-blow description of what this sample does, and how it does it? If so, send mail -- the more mail I get on this, the higher the write-up goes on my to-do list.

To build the sample: Unzip to a directory of your choice, keeping the subdirectory structure intact. Open the sockhim.dsw workspace with VC++ 6.0 (I am using SP3) and build the srv project. (The cli project might develop into a stress-testing client later, but unless there is large and lively interest, don't hold your breath.) Note that I am using the Platform SDK headers/libs, and I strongly recommend that you do the same.

To run the sample: Run srv.exe (or srvd.exe). It understands the following command line switches: -?, -h display a short usage note; -p <number> sets the port for srv to listen on (it binds to INADDR_ANY; binding only to specific interfaces or IP addresses is left as an exercise for you); -s <number> sets the maximum number of simultaneous connections to that number; -t <number> sets the maximum number of threads to that number; -c <number> tells the IOCP how many concurrent threads to allow -- 0 is the default, one per CPU. Run "srv.exe -?" to see the default values.

To play with the sample: Fire up a telnet client and tell it to connect to the port you are using for srv.exe. I recommend enabling local echo. If you don't, you won't see anything until you hit the RETURN key. Commands are one per line, with a blank or tab separating the command from its argument (where applicable). Start with "?" or "help". Note that the "parser" (cough, cough) is extremely simple-minded: it hates extraneous blanks, doesn't understand quoted strings, and offers no line editing at all, not even backspace.

sockhim.zip, 18 KB: Sockets-over-IOCPs sample.