A few weeks ago, I had the pleasure to take part in a local 24-hour long, programming marathon (greets to my team: Pawel and Wojtek!). Due to the nature of the competition, I was obliged to create a simple class, making it possible to redirect sockets to standard i/o (stdin / stdout), which would greatly facilitate the communication process with the contest server. Because of the fact that we were going to work on different system platforms – both Microsoft Windows and GNU/Linux, the class had to be as cross-platform compatible as it was only possible. And so the CTcpFwd class, presented today, came into existence.
After the event was over, I decided to standardize the code and apply some minor fixes – currently, it is supposed to be a fully functional module. What should be kept in mind, though, is the fact that the code is released as a Proof of Concept project – its main purpose is to present the exact way of how the stdin / stdout file descriptors can be tampered with, on Windows – as it turns out, it is not as simple as one might assume.
This tiny class lets the programmer create and close multiple named, remote connections (Connect and Disconnect methods), as well as switch the current stream associated with stdin/stdout (SwitchStdin and SwitchStdout routines), using the names declared previously. By default, the class turns off both the Nagle’s buffering algorithm for the sockets (TCP_NODELAY flag) and the standard i/o buffering. Some exemplary usage of CTcpFwd follows:
CTcpFwd Sock("Google","google.com",80); puts("Sending a request..."); Sock.SwitchStdout("Google"); printf("GET http://www.google.com/ HTTP/1.1\n" "Host: http://www.google.com/\n\n"); Sock.SwitchStdout("DefaultStdout"); Sock.SwitchStdin("Google"); while(fgets(buffer,sizeof(buffer),stdin)) printf("%s",buffer);
The above code connects to the google.com host on the HTTP port, sends a simple request and prints the server response on the screen – everything is happening through standard i/o.
A complete package, containing the class source code (written in C++) can be downloaded from here (6kB).
As I’ll have more time, I’ll try to post some wider explanation of the msvcrt-specific mechanisms utilized in the code, soon. If any problems with either the compilation or class performance are encountered, please contact me directly ;>
Comments obviously always welcome ;>