<<

Winsock Programmer's FAQ
Basic Winsock Examples

>>

These examples show you how to implement several of the various I/O strategies that Winsock allows. (You can get an idea of how many I/O strategies are possible by reading the FAQ article Which I/O Strategy Should I Use?)

The Echo Protocol

Each example is either an echo client or an echo server. The servers read everything they receive and send it back verbatim. The clients send data to the server and check that the reply matches what was sent. The client programs can wait a bit before shutting the connection down, so that you can run multiple clients to test multi-connection servers.

The echo server idea lets us focus more on the structure of the program and less on its function, and yet still provide a fairly functional program. I could have chosen something more substantial, like a "chat" program, but then you end up spending more time on user interface details than on Winsock programming issues.

The clients will actually work with any echo server: Windows NT, Windows 2000 and most Unixes have an optional service that sits on port 7 and works just like my servers do. This lets you test echo over the Internet to a host that you don't control. You may have a hard time finding such a host, though, because port 7 echo can be used to attack a network, so most admins turn that feature off.

Structure and Philosophy

Although these programs are "minimal" in the sense that they don't do much, they are still complete in that they do all the proper error checking, shut their connections down gracefully, are fully commented, etc. Some thought has been given to making it easy to swipe pieces of code from these examples.

These programs all follow the same form as much as possible. Any time you find two functions named the same in two different examples, you can be sure that they have the same purpose, so you can study them comparatively. For example, you can study AcceptConnection() in the basic and threaded servers to see how threads change the way you accept client connections.

Coming Real Soon Now...

Eventually there will be more examples here. The ideas I currently have are:

  • A single-threaded server that uses WSAEventSelect() instead of select()
  • Overlapped I/O client
  • Overlapped I/O server
  • Endpoint-based client
  • ACE-based client
  • ACE-based server
  • multi-threaded client (useful for stress-testing stacks and server programs)

Supported Compilers

I currently test all console mode programs with the command line compiler from Microsoft Visual C++ 5.0 SP3, the free version of Borland C++ 5.5, and the Cygwin 1.0 port of the GNU tools to Win32 (EGCS 1.12). The Makefile below is compatible with the make tools from all three environments.

The GUI programs are built around MFC, and tested under Visual C++ 5.0. This is not an arbitrary decision: Aside from the simplifications in MFC itself, these programs use some of my MFC-based framework code which makes the examples more powerful and easier to follow. If I wrote straight Win32 code, you'd end up with either weaker examples, or harder-to-follow code.

Common Program Files

You should probably download all of these before you begin, because all the console mode examples require all of these files. The GUI programs require some of the files in this set, too.

    Makefile - The Makefile that builds the console mode examples. (Not required, but makes building the examples easier.)

    main.cpp - The main() function for the console mode example programs. Parses the command line, initializes Winsock, calls the example's driver function, and then shuts Winsock back down.

    ws-util.cpp - A set of Winsock utility functions used by all the example programs.

    ws-util.h - Header file for ws-util.cpp.

The Examples

Each of these examples illustrates a particular design choice. You can read more about the plusses and minuses of each choice in the FAQ article Which I/O Strategy Should I Use?. Obviously, no one design choice is best for all situations, or we would not have so many choices. Between the article's advice and these concrete examples, you should be able to make your decision fairly easily.

You can test each server's multi-connection handling by running it in one command window and then running two or more instances of the basic client from another command window. The basic client has a shutdown delay that makes it keep its connection open for a bit after it receives the reply from the server. The delay gives you time to switch among a few command windows, to run a client from each before the first clients start closing their connections.

    Basic blocking client - A client that uses blocking sockets. This is the simplest of the programs here.

    Asynchronous client - A client that uses asynchronous sockets. This program is a GUI MFC program, but it does not use CAsyncSocket or its derivatives.

    CAsyncSocket-based client - A client that uses MFC's asynchronous sockets wrapper class: CAsyncSocket.

    Basic blocking server - A simple server that uses blocking sockets.

    Basic multithreaded server - A server that sends each new connection off to its own thread to be handled while the main thread sits in a loop accepting connections.

    select()-based server - A server that handles many connections using the select() function to manage them all within a single thread.


<< Example Programs Basic Blocking Client >>
Last modified on 3 July 2000 at 19:13 UTC-7 Please send corrections to tangent@cyberport.com.
< Go to the main FAQ page
<< Go to my Programming pages
<<< Go to my Home Page