DWise1's Sockets Quick Start


HARD HAT AREA

WATCH YOUR STEP

Introduction

There are several different aspects to sockets programming, but the most basic question is: how do I get started and what do I need? My goal on this page is to answer that most basic question; on my other pages I will answer the more detailed questions.


Getting Started

First Round of Follow-up Questions

The really good questions are the ones whose answers raise even more questions. Without all those new questions, we wouldn't know what we need to learn next.

That most basic question raises these questions immediately:

What programming language do I need to use?
I've found that just about any programming language any more has support for sockets; eg, C, C++, C#, Java, Perl, Python, Lua. Most of that support includes the basic sockets functions, but some (eg, C# and Java) hide a lot of the lower-level functions with object-oriented programming classes.

Sockets were originally implemented with C, so that's the language that I use on this site. Regardless of the language that you choose to use, the same principles and basic functionality should still apply.

What special software tools do I need to get?
None. If you already program, then you should already have a compiler. And if your compiler is less than 20 years old, then you should already have all the software tools you need. There are no special libraries or development tools to buy. Sockets support comes with almost every compiler that I can think of.

Of course, if you have a specialized compiler, such as for embedded programming, that support may not be there. And on Windows if you have an old 16-bit compiler (eg, Turbo C, which is still being forced on many students in the third world), then that would undoubtedly not be compatible with the 32-bit Winsock DLL on your system. If you need a current compiler, many are available on-line for free (eg, MinGW gcc, Microsoft Visual C++ Express).

What kind of special hardware do I need to set up a network?
To start with, none. Every computer that has TCP/IP installed on it has a special loopback address called localhost (127.0.0.1). When you develop your sockets programs (commonly in pairs, a client and a server), you can then run them both on the same computer to test them out. In fact, it's a best practice to do your initial testing of your programs through localhost, since that eliminates other possible problems that might cause confusion during debugging.

When you do move up to actually running your client and server on different computers, then that will be when you will need to deal with cables (both cross-over and straight), hubs, routers, etc. That is also when you will need to understand IP addressing and how to set addresses. And since individual computers can have firewalls set up, that could be another issue you would need to contend with. Do you see now why I recommend starting with localhost?

How do I compile a sockets program?
That depends on a few factors:

  1. What language are you using? Obviously, different languages would be compiled differently. You know best how to compile a program in your language of choice. Remember that I am using C in my discussions and examples.

  2. What specific compiler are you using and on what operating system? The importance of the operating system is because of differences in the operating systems' support for sockets. Sockets were created under BSD UNIX and so UNIX systems (including POSIX, BSD, and Linux) offer native support since sockets are an integral part of the operating system. Microsoft Windows make use of an industry library called Winsock ("Windows Sockets"), which is not an integral part of Windows, but rather is implemented with a Winsock DLL ("dynamically linked library"; actually, a lot of Windows is implemented with DLLs). As a result, compiling and building a sockets program will be different on Windows than on a UNIX system. In addition to that, there may be minor differences in the build setup in different compilers.

    I discuss this more fully below.

    I would also point out that since Apple's OS X operating system is based on a BSD kernel, its support for sockets should be the same as in other UNIX systems. I do not have any practical experience with Macs, so this is an informed assumption.

How do I write a sockets program?
Now this is the big question. It is so big that I have an entirely other page and more devoted to answering it. But this is also a question that we can safely postpone for the moment. For the moment, your main concern is how to compile and build and run a sockets program. For that, you should start with existing source code that's known to work. Then only after you have proven how to build and run a program should you attempt to write your own, which is your ultimate goal.

If you have a book that covers sockets programming, then you will find several examples there. There is also a lot of source code available on-line that you can choose from. In addition, I've posted some sample code on my Sample Network Applications with Source Code page.

When choosing sample source code, you need to be aware of a couple caveats:

  1. Winsock or UNIX? There are distinctive differences between the source code that's compiled under a UNIX system or under Windows. In addition, most of the source code that's posted on-line is for UNIX, so if you were to try to compile that under Windows it would fail. As you gain experience, you will be able to tell them apart immediately, but in the beginning the easiest way is to look at the #include statements; if the header file, winsock.h or winsock2.h, is included, then it's a Winsock program, otherwise it's UNIX.

    I wrote my sample programs to be usable on either Windows or UNIX. At the top of the code (ie, after the long comment block) is a macro definition, WINSOCK_EXAMPLE. The comment directly above it tells you whether to #define it or to #undef it. Reviewing that code will also show you the most basic differences between a Winsock and a UNIX program.

  2. What version of C? When Kernighan and Ritchie created C in the 1970's, they wrote a book, The C Programming Language, which became the default manual for the language. Then in 1989 the first official ANSI standard was released for the language. The new standard was called "ANSI C" and the defacto standard that preceded ANSI C came to be called, "K&R". There are many differences between ANSI C and K&R, most notably in how functions are written. And FYI, Kernighan and Ritchie later wrote a second edition of The C Programming Language, which has "ANSI C" stamped on the front cover, with all its code upgraded to ANSI C, and with an appendix listing the new features of ANSI C for K&R programmers to come up to speed.

    The reason for bringing up K&R C is because there's still a lot of source code on-line that was written in the K&R style. And because most modern C compilers will not compile K&R code, but rather they insist on ANSI C.

    Another version problem that's starting to appear is the next standard that was released in 1999 and which is referred to as "C99". The problem there is that support for C99 is spotty at best. Microsoft does not support it, nor does MinGW gcc. gcc on Linux does support it. If you try to compile C99 code with a compiler that does not support it, then it will fail. The problem lies in the fact that UNIX-centric programmers will post code in C99 with no thought of portability. And again, since my samples were written in ANSI C and not in C99, they would be a good choice for testing your ability to build and run a program.


Building the Program's Executable

Once you have the source code, you need to compile it and build the executable. Of course, the details will differ depending on what operating system and development environment you're using, but the concerns will still be the same. The most basic concern is that the sockets functions are part of a library, which means that you use it in your code just as you would any other library.

Here are how you build the executable in UNIX/Linux or Windows, and how I assume you would do it on a Mac:

UNIX/Linux
You just compile it. From the command line:
gcc -Wall myprog.c -o myexe
Since sockets support is an integral part of the operating system, the sockets library code gets linked in automatically, like the library code for stdio. You do not need to do anything special.

Apple's OS X
I have no practical experience with this platform, but from what I've read and would assume, it's just like compiling the program under UNIX or Linux. OS X uses BSD UNIX for its kernel, so it should behave the same. However, I have no idea about OS9 or earlier versions.

Windows (Winsock)
Here is where things are different. Since support for sockets is added on, you will need to link in the Winsock library explicitly. And exactly how and where you do that depends on what compiler/development system you are using.

You will use either one of two library files:

  1. wsock32.lib -- this is the 32-bit static library for Winsock 1.1.
  2. ws2_32.lib -- this is the 32-bit static library for Winsock 2.
It is generally advisable to use Winsock 2; correspondingly, you would have included the Winsock 2 header file, winsock2.h, in the source code instead of winsock.h.

Most integrated development environments (IDEs) are GUIs and hence they have a system of menus. Most IDEs also organize programs into projects or "solutions" and include tools for project management. Somewhere there should be a dialog of "project options" or the like where you can add libraries to the linker. So it's a matter for finding the right menu path to the project.

Visual Studio 2008 Example
In the Main Menu under Project there is a submenu item <project name> Properties ... which opens the project's Property Pages. In the treeview in the left pane, I expand the nodes Configuration Properties, Linker and I select Input. In the right pane, the top item I see listed is Additional Dependencies. That is where I add the Winsock2 library file, ws2_32.lib.

MinGW gcc Example
While MinGW gcc is a command-line compiler (and that is the only way that I use it), it is also bundled with and embedded in several freeware IDEs like Dev-C++. When found within an IDE, it's yet another situation of having to search through the menus to find where to add the library file. Though since MinGW gcc is a port of the Linux gcc compiler, its library files are named differently. The 32-bit Winsock 2 library is libws2_32.a, though to refer to it you normally drop the .a file extension and the "lib" prefix, leaving just ws2_32.

Building a sockets program from the command line would look this:

gcc -Wall myprog.c -lws2_32 -o myexe
As you can see, it is virtually identical to the Linux command, except you also have to add a "-l" ("minus ell") option to link in the Winsock2 library.
The result will be an executable file that you can execute just like any other executable file on your system.

Running the Program

Now that you have an executable, you will want to run it. Like I said, you run it just like you would any other executable on your system with all the same considerations and concerns. But here are a few more things to keep in mind:

Remember that you are running two programs.
The basic purpose for network programming is for two programs to communicate with each other. Also, the basic model for network programming is the client/server relationship in which one program, the server, waits for the other, the client, to contact it or connect to it. So that means that you are going to be running two programs, a server and a client.

There can also be a situation in which you want to communicate with an existing program, so you only create one program; eg, you may have written an NTP (Network Time Protocol) client that you will test using an existing NTP server somewhere. This is actually a very good idea if you are implementing a existing protocol, since you would want your client or server to work with other programs that also implement that protocol -- if you write both the client and the server and you make a fundamental mistake in both, then they'd work with each other but with no one else. Both Windows and Linux allow you to run certain services on your computer, which may prove useful.

Run both programs on the same computer.
This is a recommended practice, especially in the earlier stages of development and debugging, since it allows you to concentrate on the programs themselves and not have to worry about network issues (eg, bad cables, addressing problems, firewalls). This way, if you encounter problems, then you know it's the programs themselves.

Both programs must run the same protocol (TCP vs UDP)
The programs will use either of two transport protocols: Transmission Control Protocol (TCP) and Uniform Datagram Protocol (UDP). These two protocols are different and do not mix. There are even two sets of address ports: the tcp ports and the udp ports. If the server is TCP, then the client must also be TCP; a UDP client simply cannot talk with a TCP server. Similarly, if the server is UDP, then the client must also be UDP; a TCP client simply cannot talk with a UDP server.

This mistake is easier to make than you might think. I've seen it made and I've made it myself.

Start the server first, then the client.
Since the server listens and waits for a client to connect to it or to contact it, then obviously the server needs to be running when the client tries to connect or to communicate.

Be aware that you may need to run the server on a different port.
There are situations which may require you to run the server on a different port than usual:
  1. Each port can only have one socket bound to it. If another server has already bound to the port you want to use, then you need to use a different one. An example of this would if you want to run an echo server on port 7, but there's already an echo server running there. You would need to instead use a different port that's not already in use.

  2. System security might not allow you to bind to the port you want. The first 1024 ports are assigned to well-known services. As a security measure, you may need to have administrative (AKA "root") privileges to be able to bind to a well-known port. If you lack that level of privilege, then you will need to instead pick one of the 16,383 ports between 49,152 and 65,535.

To facilitate running the server on a different port, the port number is an optional command-line argument in my sample programs.

If you need to find a free port, you can use the command-line utility, netstat -an, which lists all ports that are currently in use and what their status is.

Be sure of the IP Addresses and that they are on the right networks

Mistake #1. Trying to talk to a host on a LAN with wrong network address.
Even if both computers are connected together directly with a cross-over cable and are sitting side-by-side, if their IP addresses do not place them on the same network (ie, if the network portion of their IP addresses are not the same), then they will never be able to talk with each other.

The reason for this is that TCP/IP has two entirely different ways of resolving the IP address to a physical MAC address and which one it uses depends on whether the hosts are on the same network or not. For more information, refer to my discussion, So Why do They Need to be on the Same Network?. And for how to solve this problem, refer to my discussion, Finally, How to Tell Whether Two Addresses are on the Same Network, though you may need to read the preceding material on addressing theory and subnet masks in order to understand the solution.












#include <stdlib.h>     /* for exit() */
#include <stdio.h>      /* for printf(), fprintf() */
#include <string.h>     /* for string functions  */
#ifdef WINSOCK_EXAMPLE
#include <winsock2.h>    /* for socket(),... */
#else
#include <unistd.h>     /* for close() */
#include <sys/socket.h> /* for socket(),... */
#include <netinet/in.h> /* for socket(),... */
#include <arpa/inet.h>  /* for inet_addr() */
#endif    

Return to Top of Page
Return to DWise1's Programming Home Page

Contact me.


Share and enjoy!

First uploaded on 2002 November 08.
Updated on 2011 September 10.