DWise1's Sockets Programming Pages

Sample Network Applications with Source Code


HARD HAT AREA

WATCH YOUR STEP

Introduction

In studying sockets programming, I've written a handful of short programs as learning tools, as test-beds, and as utilities. So I've started to clean up that code and to comment it properly in preparation to post it on this page. That way, you will have sample code that may help you as you learn sockets programming.

I've started with six short simple example programs that implement the three basic types of client/server application that I discussed on my Basic Application Structure web page. And I'll add on more programs as I get around to cleaning up their source code and applying meaningful comments that will help you make sense of what I'm doing there. The links for downloading the source code are listed at the end of this page.

I am writing these sample programs so that they could be compiled either under Windows or under UNIX/Linux. I've provided General Instructions for compiling them on either system.

These are also all command-line applications (AKA "console apps"). While I haven't yet explored the Windows programming aspect of Winsock (ie, its WSA* functions that extend sockets to do Windows messaging), when and if I do then I will treat those sample programs in much the same say that I'll treat samples in other programming languages. Again, don't expect this any time soon.

I will add more applications to this page in the future.

And I plan to expand my site in the future to include sockets programming in other languages, such as Java and perl -- actually, my very first study of sockets programming was in perl with Lincoln Stein's book, "Network Programming with Perl". When that happens (and it will by no means be any time soon), I will either add a section on this page for those sample programs or else create a new page for them.

Please keep in mind that these programs are for educational purposes only and are not meant for commercial use. As such, you will use them at your own risk and will not be able to hold me responsible for any damage they might cause, either directly or indirectly. Before you download any code, please be sure to read the disclaimer in the very next section.


Disclaimer

The examples I present on these web pages are slightly modified versions of example programs from The Pocket Guide to TCP/IP Sockets: C Version by Michael J. Donahoo and Kenneth L. Calvert (second edition title: TCP/IP Sockets in C: Practical Guide for Programmers). I recommend this book highly as a concise quick-start guide to beginning TCP/IP sockets programming. The original UNIX source code is freely available from their web site at http://cs.baylor.edu/~donahoo/PocketSocket/textcode.html and the Winsock version of the code at http://cs.baylor.edu/~donahoo/PocketSocket/winsock.html. The second-edition website is at http://cs.ecs.baylor.edu/~donahoo/practical/CSockets/. You should check out both sites, since not all of the links are duplicated between them and some of the source code may have changed in the second edition.

On their book's web site, Michael J. Donahoo and Kenneth L. Calvert have posted their disclaimer, which states:

"The purpose of this book is to provide general information about network programming as of the book's publication date. The authors have included sample code that is intended for the sole purpose of illustrating the use of the sockets API. Neither the authors nor the publisher are aware of any third party patents or proprietary rights that may cover any sample of any kind. The authors and the Publisher DISCLAIM ALL EXPRESS AND IMPLIED WARRANTIES, including warranties of merchantability and fitness for any particular purpose. Your use or reliance upon any sample code or other information in this book will be at your own risk. No one should use any sample code (or illustrations) from this book in any software application without first obtaining competent legal advice."
To that, I add my own disclaimer:

General Instructions

Windows

  1. Download the ZIP file containing the source files you're interested in.

  2. Extract the source files with WinZIP or whatever utility you use for ZIP files. It appears that under Windows XP, the Windows Explorer utility can open ZIP files and extract files from them.

  3. The source files are ready to be compiled under Windows:
    • The WINSOCK_EXAMPLE manifest has been defined (#define WINSOCK_EXAMPLE).

    • The files are DOS-style text files (newline == CRLF).

    • If you use Visual C++, then create an empty console application, add the source file to it, and link WS2_32.LIB into the project. For more detailed instructions, read Transitioning from UNIX to Windows Socket Programming by Paul O'Steen.

    • If you use a port of gcc that supports sockets, such as MinGW (distributed with Dev-C++), then link in the libws2_32.a library or whatever it's called in your port; eg:
          gcc -o tcpserver tcpserver.c -lws2_32

    • If you use a different development environment, then do whatever is required to create a console application that uses one of my source files as the only source and that links in whatever Winsock2 static library that development environment provides. Sorry, I can't help you there. You've got to work out those details yourself.

  4. Run the application from the command line.


UNIX/Linux

  1. Download the tarball containing the source files you're interested in.

  2. Extract the file with the tar utility; eg:
        tar xvfz basic_apps.tar.gz

  3. The source files are ready to be compiled:
    • The WINSOCK_EXAMPLE manifest has been undefined (#undef WINSOCK_EXAMPLE).

    • The files are UNIX-style text files (newline == LF).

    • Compile the programs. Under Linux, you do not need to link in any extra libraries; eg:
          gcc -o tcp_server tcp_server.c

  4. Run the application from the command line.

Links to the Source Code

While I've tried to make the following samples compilable under both Windows and Linux, since I mainly work in Windows and since some of what I'm doing (eg, multitasking) will be specific to Windows, I won't always have a Linux version. I apologize for that in advance. Though you should still be able to read the code and to modify it for Linux. The links follow:

  • Basic TCP and UDP echo servers and clients
  • I wrote these short simple example programs to demonstrate how to implement the basic types of TCP and UDP client/server applications that I have discussed on my Basic Application Structure web page. Each program is a contained within a single source file. Although the programs were written in C, you should still be able to apply the principles of the code to whatever language you're working in.

    These implement the echo service, which is a simple network test in which the server simply echos back to the client everything that the client sends to it. The echo service is described in RFC 862, one of the short ones.

  • Broadcast time server and client
  • I wrote these short simple example programs to demonstrate how to implement the broadcast client/server model.

    This client/server application implements the UDP form of the daytime protocol, RFC 867, in that the client listens for the server to broadcast the time, which the client then prints out to stdout.

  • Both the echo and the broadcast time servers and clients are distributed together in the same archive files:


  • Multi-client TCP and UDP echo servers
  • These are the next phase of echo servers. These clients and servers establish extended sessions in which the client can send several strings to be echoed back by the server. The servers can also handle multiple clients, arbitrarily limited to 9. And the TCP servers and clients implement the Graceful Shutdown.

    The servers handle multiple clients in different ways as described on my page, Dealing With and Getting Around Blocking Sockets:

    1. echod uses the select() function as described here.

    2. echonbd uses non-blocking sockets as described here.

    3. echomtd uses multithreading as described here. However, it uses Windows multithreading instead of Linux' pthreads, but if you're experienced with pthreads you shouldn't have much of a problem converting it.

      The main thread initializes everything, starts the AcceptThread, and then sits back and waits for the keyboard signal to terminate. The AcceptThread would just sit there blocked by its accept() call until a client would connect, whereupon it would create a ClientThread for that client and then go back to being blocked by accept(). The ClientTread conducts the session with that client, as the other ClientThreads do concurrently with the other clients, and when the client disconnects then the ClientThread shuts down the connection, updates the server's client data, and then terminates; again, the ClientThread sits there blocked by its recv() until the client sends it something (which includes notification from the client that it's disconnecting).

      In a second iteration, I moved all printf's to a critical section, a synchronization mechanism to restrict access to a shared resource, which had the effect of forcing some of the thread.

    4. echoudpd is that experiment I considered in which I wanted to see whether a simple UDP server wouldn't be able to handle multiple clients as-is. So I took the UDP echo server from above, just as it is, and modified the client to bombard it constantly with a fixed message and keep track of how many dropped messages and other errors it detected. 20 clients hammered away to the server. Each and every one of them reported no dropped messages and no errors.

    In order to stress-test the servers, I modified the clients to include a -r option. In normal operation, the client prompts you to enter a string to be echoed, which happens when you press enter. But if you choose option -r, then the client will blast the server repeatedly with that old standard 70-character typing exercise:

    Now is the time for all good men to come to the aid of their country.
    Then have all 9 clients doing the same thing at the same time. I was surprised to see that the servers could keep up and continue to service all the clients.

    Again, each program is a contained within a single C source file.

  • Windows

  • UDPTimeC time client
  • I wrote this utility when we were working on a Network Time Protocol (NTP) application. It's just the UDP time client which requests the time from a server and displays the data it receives on the stdout output. It supports both NTP (RFC 2030) and the time service (AKA "timserver", on port 37, RFC 868).

    One of its interesting features, pedagoguically speaking, is how it inserts and extracts binary data into and out of a packet. This is one of the stumbling blocks for novices and a common question that gets raised. RFC 2030 specificies an exact format for an NTP data packet, which I follow in this program. I use this format as an example in my Formatting Packet Data page.

    There is a plethora of NTP servers out there (refer to this site for a list), but it's hard to find any time servers. So that you can test the time protocol features of UDPTIMEC, this download also includes a time server (port 37), UDPTIMED, which will function either as a regular time server or as a broadcast server, though only supporting UDP, not TCP, as the name implies.

    You can also misuse UDPTIMEC to view hex dumps of responses from other servers. For example, I enabled the daytime service (port 13, RFC 867) and the "Quote of the day" service (AKA "qtod" or "quote", port 17, RFC 865) on my XP box and then used UDPTIMEC to query them both:

    C:>udptimec localhost 13
    Sending 0-byte query to localhost:daytime [127.0.0.1:13]
    Received 21 bytes from localhost [127.0.0.1:13]
    39 3A 31 33 3A 35 30 20 41 4D 20 31 2F 31 37 2F    9:13:50 AM 1/17/
    32 30 30 38 0A                                     2008.
     **********
    
    C:>udptimec localhost 17
    Sending 0-byte query to localhost:qotd [127.0.0.1:17]
    Received 107 bytes from localhost [127.0.0.1:17]
    22 57 65 20 77 61 6E 74 20 61 20 66 65 77 20 6D    "We want a few m
    61 64 20 70 65 6F 70 6C 65 20 6E 6F 77 2E 20 53    ad people now. S
    65 65 20 77 68 65 72 65 20 74 68 65 20 73 61 6E    ee where the san
    65 20 6F 6E 65 73 20 68 61 76 65 20 6C 61 6E 64    e ones have land
    65 64 20 75 73 21 22 0D 0A 20 47 65 6F 72 67 65    ed us!".. George
    20 42 65 72 6E 61 72 64 20 53 68 61 77 20 28 31     Bernard Shaw (1
    38 35 36 2D 31 39 35 30 29 0D 0A                   856-1950)..
     **********
    

    Of course, you could also query these text-based services with telnet, but you wouldn't get a hex dump.

    I'm only providing the Windows version of these programs. UDPTIMEC is not portable as it stands, because it uses conio in one function. However, my standard conditional compilation macros are in place and I clearly indicate which function will need to be changed, so you should be able to port it to UNIX/Linux with minimal effort.

    The ZIP file below contains both source code and Win32 executable files for both UDPTimeC and UDPTimeD.


  • Trivial FTP (tftp) client
  • TFTP is a simple file transfer protocol that's described in RFC 1350. It accomplishes the basic function of FTP (RFC 959), only without any need to log in and authenticate and without the commands for directory navigation and listing and for working with multiple files. It just gets or puts a single file, quick and dirty and presenting a gaping security hole.

    The source code still needs more clean-up and commenting. Plus, I'd like to also develop a TFTP server before I post this. That server will be the first one in which I will plan for servicing multiple clients all at the same time.


  • MiM ("Man in the Middle")
  • This was my very first network program in C. Anticipating the need to write an embedded telnet client in a Windows test utility (that project got farmed out instead), I started studying that protocol. Needless to say, I was confused about the client/server negotiations and how a client was supposed to conduct that negotiation. So, inspired by the general idea behind "man in the middle" attacks, I wrote as MiM which served as a proxy between a telnet server on my Linux box and client on my Windows box, which is also where MiM ran. The client would connect to it and it would connect to the server and then pass all the messages back and forth between the client and the server. At the same time, it wrote all that message traffic to a disk file, in binary so that I could see all the command bytes, which I would translate to a readable printout with a second utility, MUNG, that I wrote quick-and-dirty.

    This ZIP file contains the source files, mim.c and mung.c, and executables built from them with MinGW gcc.


  • Return to Top of Page
    Return to DWise1's Sockets Programming Page
    Return to DWise1's Programming Page

    Contact me.


    Share and enjoy!

    First uploaded on 2007 January 06.
    Updated on 2011 September 10.