\chapter{Networked Gaming with Linux}
\label{ch:gamenetworking}

It all started with id Software's \gametitle{Doom}. Once the number of computers with modems (mainly for surfing the bulletin board (BBS) systems of the time) had reached critical mass, it became feasible to build multiplayer games in which the players weren't sitting at the same monitor or even in the same room. There were others, but \gametitle{Doom} was the one that really got people thinking about networked gaming.

Quite frankly, modem-to-modem \gametitle{Doom} was a huge hassle. The two players had to have exactly the same version of the game, the same map (\filename{.wad}) files, and compatible modems with correct parameters. It was difficult or impossible to change game settings after the connection was established, so the players generally had to agree on these over the phone ahead of time. If the connection failed, as would frequently happen, it was hard to know whether the next phone ring would be your friend calling to explain the problem or his computer trying to redial. Nonetheless, the allure of playing against a real human halfway across town was enough to make deathmatch \gametitle{Doom} one of the most popular games of the time and to usher in a new era of online gaming.

You're in luck! Today you don't have to mess with modem init strings or design your own transport protocol to add multiplayer support to your games. Instead, you can rely on the operating system's support for TCP/IP (the Internet's workhorse protocol) and the user's existing Internet connection. It's no longer necessary to play with interrupts, serial ports, or flaky lines (though admittedly it was fun while it lasted---there's nothing quite like programming a buggy UART chip in assembly). Thanks to the Internet, it's easy to write code that communicates reliably with the other side of the world. And, of course, we all know that the primary purpose of computers and the Internet is gaming, right?

This chapter looks at the protocols and techniques that make it possible to write multiplayer games for Linux. We'll start with a quick tour of TCP/IP and the basic layout of the Internet; then we'll discuss the Linux networking interface. Finally, we'll add two-player network support to \gametitle{Penguin Warrior}.

\section{'Tis a Big Net, Quoth the Raven}
If you're reading this book (which you presumably are, or else I'm talking to myself again), there's a good chance you're an experienced netizen and are more or less familiar with the Internet's architecture. Or perhaps you're just getting into the whole mess and aren't familiar with protocols, packets, and routing. In any case, a quick refresher won't hurt.

\subsection{Internet Protocols}
The Internet is just a bunch of computers that are set up to talk to one another. The language of the Internet is \index{TCP/IP}\firstterm{TCP/IP}, a set of protocols (communications standards) that provides reliable data exchange over a wide area. \firstterm{Internet Protocol} (IP) is a simple addressing and routing system that lets computers send short messages to one another, without any guarantee that the messages will arrive intact or even show up at all. \firstterm{Transmission Control Protocol} (TCP) is a higher-level system that sits on top of IP and manages reliable point-to-point data transmission. You can use IP without TCP, but TCP depends on IP. Other protocols, such as \index{ICMP (Internet Control Message Protocol)}\firstterm{Internet Control Message Protocol} (ICMP) provide error reporting and other useful services. Together, the protocols that make up TCP/IP provide everything you need to send data anywhere in the world and to make sure it got there.

From an application (game) programming perspective, we have two main protocols to work with. \index{TCP (Transmission Control Protocol)}TCP, as we just mentioned, is good for establishing reliable data transfer connections between two computers. At the cost of a bit of overhead, it ensures that each byte sent from one end will arrive undamaged and in order at the other end. TCP is called a \index{stream protocol}\firstterm{stream} protocol because it implements a protected stream of data between two points. This is the flagship protocol of the Internet. Almost everything uses TCP, including the Web (HTTP) and file transfers (FTP). We'll use TCP to link our multiplayer version of \gametitle{Penguin Warrior} together.

\index{UDP (User Datagram Protocol)}\firstterm{User Datagram Protocol} (UDP), on the other hand, is not reliable and not connection based. It is a \firstterm{datagram} protocol---that is, it allows applications to send brief messages known as datagrams over the Internet, with no guarantee as to when the data will arrive at the other end (the assumption being that it will probably get there, if network resources can accomodate it). Packets may arrive out of order, much later, or not at all. If they do arrive, however, UDP guarantees that they will be correct and uncorrupted. UDP provides no flow control. It's easy to send UDP packets faster than the network can handle them, in which case some will probably disappear. Furthermore, there is a maximum (system-dependent) size for datagrams. This is never too low (or UDP would be useless), but you can't count on UDP to send more than a few hundred bytes per packet. Even though UDP is unreliable, it's useful in many cases. We won't use UDP in \gametitle{Penguin Warrior}, as it would greatly increase the code's complexity for only marginal performance gains.

\subsection{Addresses and Ports}
Every computer on the Internet, whether connected through a high-speed line or with a lowly dialup modem, has a unique \index{IP address}\firstterm{IP address}. This four-byte number identifies the computer's exact network location and provides the underlying IP protocol with enough information to route pieces of data to that computer from anywhere in the world. Some computers (mainly dedicated servers) keep the same (\index{IP address!static}\firstterm{static}) IP address indefinitely, but in most cases computers are assigned new (\index{IP address!dynamic}\firstterm{dynamic}) addresses each time they log on to the network. Before you can exchange data with a remote host over the Internet, you need to know its IP address. IP addresses are usually written as four one-byte parts, separated by periods (for instance, my building's router has the address \ip{128.61.59.1}). This is known as the \firstterm{dotted} representation of an IP address. We'll leave a more complete discussion of IP addresses and the mechanics of routing to other sources, since it's mostly irrelevant to our game programming needs (and quite dry).

What happens if more than one program on a single computer needs to send and receive packets at the same time? It seems as though the networking software might have trouble deciding which packets should go to which program. This would be quite a mess, especially on servers that need to handle hundreds of clients at a time. TCP/IP fixes this with the notion of \index{ports (TCP/IP)}\firstterm{ports}. A port is just a number that identifies a particular receiving program. Certain port numbers are reserved for basic networking services like FTP and HTTP, but most of them are available for programs to request and use. You can think of ports as loading dock numbers in a large shipping center. Packets are always marked with both a destination IP address and a receiving port number. When packets come in, the networking software sorts them out by port number and sends them to the corresponding programs. We'll see how this works when we dig into some socket code later on.

\subsection{Name Resolution}
\index{DNS|(}
\index{hostnames|see{dns}}
Humans are better at remembering names than numbers. As a result, IP addresses can be hard to keep track of. \firstterm{Domain Name System} (DNS) makes the Internet easier for humans to grok by associating a short name with an IP address. DNS is a distributed database---it's spread out all over the Internet. The DNS name for an IP address is called a \firstterm{hostname}, and hostnames usually belong to a \firstterm{top-level domain name} (TLD). For instance, my system's hostname is \hostname{neutron}, and it belongs to the \hostname{patentburner.com} domain (for a complete name of \hostname{neutron.patentburner.com}). If you type this name into a Web browser or any other network client,\footnote{Please, not nmap!} the program realizes that you did not type an IP address and calls DNS into play. DNS first searches the enormous \hostname{com} database, finds contact information for the \hostname{patentburner} DNS server, and queries this server for a machine by the name of \hostname{neutron}. The \hostname{patentburner} DNS server (which resides on a friend's Linux box) locates \hostname{neutron} in a table, finds its IP address, and returns this information via the UDP protocol. All of this happens behind the scenes -- the network client has to make only a single system call to initiate the lookup. We'll demonstrate this process later in the chapter.

Keep in mind that DNS is not part of the TCP/IP protocol stack, and the Internet would work just fine without it (but humans would have a lot more trouble finding the sites they're interested in).

Simple enough? Good, let's give it a spin.
\index{DNS|)}

\section{Socket Programming 101}
\index{sockets|(}
The BSD sockets API is one of the most popular TCP/IP networking interfaces today.\footnote{The socket interface isn't limited to any particular protocol, but it's most often used with TCP/IP.} There are others, but BSD sockets has become the de facto standard for Linux and UNIX systems. The BSD sockets API isn't pretty, but it works well enough to have caught on. (You could also say this about UNIX as a whole.)

The following is a rather condensed tour. Network programming is a big subject, and it's not really the focus of this book.

\subsection{Sockets}
A \firstterm{socket} is just a file descriptor (similar to one returned by the ordinary \code{open} function) that represents a networking context. Usually a socket acts as an endpoint for a TCP connection, but they're also useful for UDP transactions. Once a socket is ready to go, you can use the familiar \code{read} and \code{write} functions to transfer data over the network, just as you'd access a normal file. To use an analogy that's been beaten to death over the years, a socket is like a handset connected to a telephone network. Once it's connected to another endpoint (by initiating or receiving a call), you can use the handset to talk or listen to whoever or whatever is at the other end.

You can create a new, unconnected socket with the \code{socket} function. This function takes three parameters that control the socket's properties. The first specifies the socket's communication domain; there are several possibilities, but \code{PF\_INET} is probably what we want. This asks for a socket configured for IP version 4, suitable for the Internet. The next parameter can be either \code{SOCK\_STREAM} or \code{SOCK\_DGRAM}, to request a stream or datagram socket, respectively. The final parameter specifies the socket's communication protocol. \code{IPPROTO\_TCP} is an appropriate choice (for both TCP and UDP).

\begin{apiref}
\indexc{socket}
\apifunction{socket(domain, type, protocol)}
\apisynopsis{Creates a new socket, a communication endpoint that acts like a file descriptor.}
\apireturns{A new socket file descriptor (a small integer of type \code{short}), or $-1$ on error.}
\apifirstparm{domain}{Communication domain. See the \code{socket} manpage or system header files for a list of possibilities. The most likely choice is \code{PF\_INET}, for an Internet socket.}
\apinextparm{type}{Socket type. For \code{PF\_INET}, valid choices are \code{SOCK\_DGRAM} (for a UDP socket) or \code{SOCK\_STREAM} (for a TCP socket).}
\apinextparm{protocol}{Protocol that this socket will speak. For TCP and UDP, this should be \code{IPPROTO\_IP}.}
\apiendparms
\end{apiref}

Continuing the analogy, a telephone is of no use unless it's connected to something. Likewise, a socket is dead in the water until you set up a connection, either by requesting a new connection to a remote host or by accepting an incoming connection. Neither is hard, but the sockets API makes it a bit ugly.

\subsection{Connecting TCP Sockets}
\index{TCP clients|(}
To originate an Internet connection, you first need to fill in a \codei{sockaddr\_in} structure with information about the remote host---most importantly its IP address and the desired remote port number. With this information ready, you can call \code{connect} to initiate a connection attempt. This is likely to fail, so be prepared -- the Internet isn't exactly an archetype of reliability. \code{connect} takes three parameters. The first is the socket to connect, the second is a pointer to a valid \code{sockaddr\_in} structure, and the third is the length of the address structure (this is necessary since \code{connect} isn't specific to any particular protocol, and different protocols use different address lengths). \code{connect} returns 0 on success and $-1$ on failure.

\begin{apiref}
\indexc{connect}
\apifunction{connect(sock, addr, addr\_len)}
\apisynopsis{Attempts to establish a network connection with the server at the given address.}
\apireturns{0 on success, $-1$ on failure. As with most old UNIX functions, \code{connect} sets the global \code{errno} variable to the relevant error code on failure.}
\apifirstparm{sock}{Socket to connect.}
\apinextparm{addr}{Address structure. Different protocols use different versions of the address structure. \code{sockaddr\_in} is the correct version for Internet sockets.}
\apinextparm{addr\_len}{Size of the address structure, in bytes. \code{sizeof(addr)} should do the trick.}
\apiendparms
\end{apiref}

\code{sockaddr\_in} specifies the intended destination of a connection attempt. This is an Internet-specific version of the more general \code{sockaddr} address structure. To use it, set its \code{sin\_family} field to \code{AF\_INET} (Internet address family), set \code{sin\_addr} to the desired IP address, and set \code{sin\_port} to the port number you wish to connect to. There's a catch, though. We've already touched on endianness---byte ordering on different CPU architectures---and it becomes a real problem in networking. Should the four-byte IP address \ip{128.61.41.1} go across the network as the bytes 128, 61, 41, 1, or as 1, 41, 61, 128? It sounds like a silly problem, but the ``obvious'' way for a human to store information is irrelevant to a CPU, and it's not safe to make assumptions about how any given processor architecture will do it. The same problem affects port numbers, since they are two-byte integers.

\index{network byte order}\index{host byte order}\index{endianness}TCP/IP has a well-defined \firstterm{network byte order} that specifies the proper orientation of multibyte values. It doesn't really matter what this order is.\footnote{Big endian. For comparison, Intel x86 processors use little endian ordering, meaning that this \emph{will} bite you if you develop on x86 and you aren't careful.} Every system that supports BSD sockets has a set of macros for converting values to and from this byte order. On systems that use a compatible byte ordering natively, these macros do nothing, but they still exist for portability. See Table \ref{tab:endmacros} for a list of these macros. We'll use them in examples throughout this chapter. \emph{You should always use these macros where appropriate, even if your machine already uses network byte ordering.}

% FIXME: references to tab:endmacros don't work correctly, and in general
% the formatting on this page is screwy.

\begin{table}
\begin{center}
\begin{tabular}{|c|p{3in}|}
\hline
Macro & Purpose \\
\hline\hline
\code{htons(value)} & Converts \code{value} (a 16-bit integer) to network byte order. Use this macro to convert port numbers for the \code{sockaddr\_in} structure. \\
\hline
\code{htonl(value)} & Converts \code{value} (a 32-bit integer) to network byte order. Use this macro to convert IP addresses for the \code{sockaddr\_in} structure. \\
\hline
\code{ntohs(value)} & Converts \code{value} (a 16-bit integer in network byte order) back to the system's native byte order. \\
\hline
\code{ntohl(value)} & Converts \code{value} (a 32-bit integer in network byte order) back to the system's native byte order. \\
\hline
\end{tabular}
\caption{Macros for converting to and from network byte order}
\label{tab:endmacros}
\end{center}
\end{table}

There are several functions associated with the sockets API that help you convert strings to IP addresses, perform DNS lookups, and so forth. Take a look at Listing \ref{code:tcpclient}. It is a simple TCP/IP client that establishes a TCP connection to a given hostname or IP address and reads data until it's stopped. You can test this program with any simple TCP server. It will not work with Telnet servers, since Telnet uses a simple but unreadable handshaking protocol. We'll develop a server program in the next section.

\longpage
\begin{apiref}
\indexc{sockaddr\_in}
\structname{sockaddr\_in}
\structsynopsis{Specifies the destination of a connection attempt.}
\structfirstmember{sin\_port}{Port on the remote system to connect to. A 16-bit integer in network byte order.}
\structnextmember{sin\_addr}{IP address of the remote system. This is a structure of type \code{in\_addr}, containing a single \code{s\_addr} member. \code{s\_addr} is the desired 32-bit IP address in network byte order.}
\apiendparms
\end{apiref}

\begin{codelisting}{tcpclient.c}{code:tcpclient}
\begin{verbatim}
/* A simple TCP/IP client program that uses sockets. */

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>     /* Tasty UNIX mojo. */
#include <netinet/in.h> /* IPv4 socket address structres. */
#include <netdb.h>      /* Access to DNS lookups. */
#include <arpa/inet.h>  /* inet_ntop function. */
#include <sys/socket.h> /* Socket functions. */

struct hostent *hostlist;   /* List of hosts returned
                               by gethostbyname. */
char dotted_ip[15];         /* Buffer for converting
                               the resolved address to
                               a readable format. */
int port;                   /* Port number. */
int sock;                   /* Our connection socket. */
struct sockaddr_in sa;      /* Connection address. */


/* This function gets called whenever the user presses
   Ctrl-C. See the signal(2) manpage for more information. */
void signal_handler(int signum)
{
    switch (signum) {
    case SIGINT:
        printf("\nReceived interrupt signal. Exiting.\n");
        close(sock);
        exit(0);
                        
    default:
        printf("\nUnknown signal received. Ignoring.\n");
    }
}



int main(int argc, char *argv[])
{

    /* Make sure we received two arguments,
       a hostname and a port number. */
    if (argc < 3) {
        printf("Simple TCP/IP client.\n");
        printf("Usage: %s <hostname or IP> <port>\n", argv[0]);
        return 1;
    }

    /* Look up the hostname with DNS. gethostbyname
       (at least most UNIX versions of it) properly
       handles dotted IP addresses as well as hostnames. */
    printf("Looking up %s...\n", argv[1]);
    hostlist = gethostbyname(argv[1]);
    if (hostlist == NULL) {
        printf("Unable to resolve %s.\n", argv[1]);
        return 1;
    }
        
    /* Good, we have an address. However, some sites
       are moving over to IPv6 (the newer version of
       IP), and we're not ready for it (since it uses
       a new address format). It's a good idea to check
       for this. */
    if (hostlist->h_addrtype != AF_INET) {
        printf("%s doesn't seem to be an IPv4 address.\n",
               argv[1]);
        return 1;
    }

    /* inet_ntop converts a 32-bit IP address to
       the dotted string notation (suitable for printing).
       hostlist->h_addr_list is an array of possible addresses
       (in case a name resolves to more than on IP). In most
       cases we just want the first. */
    inet_ntop(AF_INET, hostlist->h_addr_list[0], dotted_ip, 15);
    printf("Resolved %s to %s.\n", argv[1], dotted_ip);

    /* Create a socket for the connection. */
    sock = socket(PF_INET, SOCK_STREAM, IPPROTO_IP);
    if (sock < 0) {
        printf("Unable to create a socket: %s\n",
               strerror(errno));
        return 1;
    }

    /* Fill in the sockaddr_in structure. The address is
       already in network byte order (from the gethostbyname
       call). We need to convert the port number with the htons
       macro. Before we do anything else, we'll zero out the
       entire structure. */
    memset(&sa, 0, sizeof(struct sockaddr_in));

    port = atoi(argv[2]);
    sa.sin_port = htons(port);
        
    /* The IP address was returned as a char * for
       various reasons.
       Just memcpy it into the sockaddr_in structure. */
    memcpy(&sa.sin_addr, hostlist->h_addr_list[0],
           hostlist->h_length);
        
    /* This is an Internet socket. */
    sa.sin_family = AF_INET;

    /* Connect! */
    printf("Trying %s on port %i...\n", dotted_ip, port);
    if (connect(sock, (struct sockaddr *)&sa, sizeof(sa)) < 0) {
        printf("Unable to connect: %s\n",
               strerror(errno));
        return 1;
    }

    printf("Connected! Reading data. Press Ctrl-C to quit.\n");
        
    /* Install a signal handler for Ctrl-C (SIGINT).
       See the signal(2) manpage for more information. */
    signal(SIGINT, signal_handler);

    /* Read data until we encounter an error. */
    for (;;) {
        char ch;
        int amt;

        /* Read one byte at a time.
           This is quite inefficient. */
        amt = read(sock, &ch, 1);

        /* ALWAYS check for errors on network reads.
           They are MUCH less reliable than local
           file accesses. */
        if (amt < 0) {
            printf("\nRead error: %s\n",
                   strerror(errno));
            break;
        } else if (amt == 0) {
            /* A zero-byte read means the connection
               has been closed. read waits until it
               can return at least one byte. */
            printf("\nConnection closed by remote system.\n");
            break;
        }

        /* Write the character to stdout. */
        putchar(ch);
        fflush(stdout);
    }

    /* Close the connection. */
    printf("Closing socket.\n");
    close(sock);

    return 0;
}
\end{verbatim}
\end{codelisting}

\longpage
Let's start from the top. Networking programs generally include a lot of extra headers. In addition to the usual \filename{stdio.h} and \filename{stdlib.h}, we need (in no particular order) \filename{unistd.h} (useful UNIXish functions), \filename{netinet/in.h} (for the \code{in\_addr} and \code{sockaddr\_in} types), \filename{netdb.h} (for DNS), \filename{arpa/inet.h} (for \code{inet\_ntop} and other conversion functions), and \filename{sys/socket.h} (for \code{socket} and related functions). To make our lives even more complicated, these headers may vary between sockets implementations (between UNIX flavors). This is one case in which the ``shotgun include'' strategy might not be a bad idea---when in doubt, include them all. (A better idea is to use Autoconf.)

We begin \code{main} by looking up the IP address of the remote system. The user can pass either an IP address or a hostname on the command line, and we use \code{gethostbyname} to convert this to a 32-bit IP address. \code{gethostbyname} takes a string, which can be either an IP address in dotted notation or a hostname, and returns a pointer to a structure that contains a list of possible addresses.

\begin{apiref}
\indexc{gethostbyname}
\apifunction{gethostbyname(hostname)}
\apisynopsis{Performs a DNS or \filename{/etc/hosts} lookup on the given hostname. UNIX implementations properly handle dotted IP addresses as well. (A recent version of Windows did not; this may have changed by now, though.)}
\apireturns{Pointer to a \code{hostent} structure that contains a list of possible IP addresses. It's possible for a single hostname to correspond to multiple IP addresses. In most cases you should just take the first address in the list. If the lookup fails, \code{gethostbyname} returns \code{NULL}.}
\apifirstparm{hostname}{Hostname to look up (such as \code{neutron.patentburner.com}), or an IP address in dotted notation (such as \code{128.61.59.45}).}
\apiendparms
\end{apiref}

Once we have a valid IP address for the remote system, we prepare a \code{sockaddr\_in} structure. \code{sockaddr\_in} requires values in network byte order. The IP address returned by \code{gethostbyname} is ready to go, but we need to convert the port number manually (with \code{htons}). We're working with the Internet (IPv4) as opposed to an IPv6 or IPX network, so we set the address family of the \code{sockaddr\_in} structure to \code{AF\_INET}.

Now it's time to actually make the connection. We call \code{connect} with the socket and the address structure. If the connection succeeds, the socket is ready to go, and we can read and write data with it.

A more interesting TCP client might actually do something with the socket at this point, but our client just reads data until it loses the connection. With normal files, you can be fairly certain that \code{read} will return the full amount of data you requested, unless it hits the end of the file. Sockets are considerably more volatile. The Internet is not a reliable medium, and it takes time to transfer data. It is very likely that \code{read} won't return as many bytes of data as you requested (though it'll always return at least one byte as long as the connection is still alive).

Finally, we close the socket and exit. \code{close} attempts to cleanly shut down the given socket, sending any remaining data before it does so. By default, \code{close} returns immediately and lets the networking system perform the shutdown in the background.

\begin{note}{Signal Handlers}
\index{signal handlers}
Listing \ref{code:tcpclient} catches interrupts (\keysym{Ctrl-C} keypresses) with a \firstterm{signal handler}. If you're new to UNIX programming, this is probably new to you; signals don't show up much in other operating systems. A \firstterm{signal} is just a way for the operating system to notify a running program about an important event, such as an interrupt (\code{SIGINT}), a program-requested timed alarm (\code{SIGALRM}), or even a memory access violation (\code{SIGSEGV}). By default most signals are ignored or handled without your program's involvement, but you can use the \code{signal} function to associate a handler function with a particular signal.
\end{note}

\begin{apiref}
\indexc{read}
\apifunction{read(sock, ptr, len)}
\apisynopsis{Attempts to read \code{len} bytes of data from the given socket into \code{buf}.}
\apireturns{Number of bytes read, or $-1$ on error. If the socket is closed (usually because the other end disconnected), \code{read} returns zero. \code{read} also returns zero if it is interrupted by a signal (which is not necessarily an error). If this happens, the global \code{errno} variable (in \filename{errno.h}) will be set to \code{EINTR}.}
\apifirstparm{sock}{Socket to read from.}
\apinextparm{ptr}{Buffer to fill with data.}
\apinextparm{len}{Maximum number of bytes to read. \code{read} may or may not actually return this much data.}
\apiendparms
\end{apiref}

\begin{apiref}
\indexc{write}
\apifunction{write(sock, buf, len)}
\apisynopsis{Attempts to write \code{len} bytes of data from \code{buf} to the given socket.}
\apireturns{Same as \code{read}. Small \code{write}s will usually process the full amount of data, but it's possible to exceed the networking system's buffer space with larger \code{write} calls.}
\apifirstparm{sock}{Socket to write to.}
\apinextparm{buf}{Buffer containing the data to send.}
\apinextparm{len}{Amount of data in the buffer. Be ready for \code{write} to not handle all of this data at once.}
\apiendparms
\end{apiref}

\index{TCP clients|)}

\subsection{Receiving TCP Connections}
\index{TCP servers|(}
Receiving network connections is just a little trickier than initiating them. First you have to create a socket and bind it to an address. \index{binding (to local ports)}\firstterm{Binding} simply tells the networking software that a socket should be associated with a certain port on the local system. (Otherwise, the kernel will chose a random one, which is no good for most types of servers.) You can bind a socket to a local port with the \code{bind} function. After binding the socket, you should inform the networking system that this is a listening socket (not one that will be used for initiating connections) and that the networking system should pay attention to connection requests on its port number. You can do this with the \code{listen} function.

Once the socket is ready, you can enter an accept loop, in which you call \code{accept} repeatedly to handle incoming connections. Each \code{accept} call returns a new socket (separate from the one you bound to the port) that's connected with a client. You use \code{close} to close each of these client sockets when you're finished with them. When you're ready to stop accepting new connections, close the listening socket.

It's worth noting that more than one client can connect to any given port number at a time. The networking software makes sure that data gets routed to the correct sockets. The exact mechanics of this are beyond our present discussion.

\begin{apiref}
\indexc{bind}
\apifunction{bind(sock, addr, addr\_len)}
\apisynopsis{Associates (binds) a socket with a port on a local interface.}
\apireturns{0 on success, $-1$ on failure.}
\apifirstparm{sock}{Socket (file descriptor) to bind.}
\apinextparm{addr}{Local address to bind the socket to. This is a pointer to a \code{sockaddr} structure. For Internet sockets, this should be a \code{sockaddr\_in} structure. \code{sin\_addr} should be set to the desired local IP address (or to \code{INADDR\_ANY} for all local IP addresses), and \code{sin\_port} should be set to the desired port number. Most systems have only one IP address, but this call also supports systems with multiple network devices. Use \code{INADDR\_ANY} unless you have a reason to do otherwise.}
\apinextparm{addr\_len}{Size of the address structure, in bytes. For Internet sockets, this should just be \code{sizeof(struct sockaddr\_in)}.}
\apiendparms
\end{apiref}

\begin{apiref}
\indexc{listen}
\apifunction{listen(sock, queue)}
\apisynopsis{Informs the networking system (the kernel, in the case of Linux) that \code{sock} is a listening (server) socket and not a normal client socket. This allows the socket to accept incoming connections. \code{listen} also sets the number of incoming connections that the networking system should allow to stack up in the connection queue.}
\apifirstparm{sock}{Socket to make into a listener.}
\apinextparm{queue}{Desired size of the connection queue. This is the number of clients that can try to connect to this server without being accepted. If you're using threads to handle clients in the background, a reasonable number might be 5 or 10. Otherwise, you'll have to base this value on your expected client load.}
\apiendparms
\end{apiref}

\begin{apiref}
\indexc{accept}
\apifunction{accept(sock, addr, addr\_len)}
\apisynopsis{Receives an incoming connection from the given socket. Stores information about the client (its IP address and port number) in \code{addr}. If there are no pending connections (nobody has tried to connect), \code{accept} waits (unless it's in nonblocking mode, which is beyond our present scope).}
\apireturns{0 on success, $-1$ on failure.}
\apifirstparm{sock}{Listening socket to check for incoming connections.}
\apinextparm{addr}{Pointer to a \code{sockaddr} structure (\code{sockaddr\_in} for Internet sockets) that will receive information about the connecting client.}
\apinextparm{addr\_len}{Pointer to an integer to receive the size of the address structure. For Internet sockets, this will be \code{sizeof(struct sockaddr\_in)}.}
\apiendparms
\end{apiref}

Now let's make a server that can talk to the client we wrote in the previous section.

\begin{codelisting}{tcpserver.c}{code:tcpserver}
\begin{verbatim}
/* Simple TCP/IP server program. */

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <sys/socket.h>

char dotted_ip[15];     /* Buffer for converting the resolved
                           address to a readable format. */
int listener;           /* Our listening socket. */
int client;             /* The current client's socket. */
int port;               /* Port we're accepting connections on. */
struct sockaddr_in sa;  /* Connection address. */
socklen_t sa_len;       /* Length of sa. This is a bit redundant
                           in simple cases, but sockets aren't just
                           for TCP/IP. */

/* This function gets called whenever the user presses Ctrl-C.
   See the signal(2) manpage for more information. */
void signal_handler(int signum)
{
    switch (signum) {
    case SIGINT:
        printf("\nReceived interrupt signal. Exiting.\n");
        close(client);
        close(listener);
        exit(0);
                        
    default:
        printf("\nUnknown signal received. Ignoring.\n");
    }
}

int main(int argc, char *argv[])
{

    /* Make sure we received two arguments,
       a hostname and a port number. */
    if (argc < 2) {
        printf("Simple TCP/IP uptime server.\n");
        printf("Usage: %s <port>\n", argv[0]);
        return 1;
    }

    port = atoi(argv[1]);

    /* Create the listener socket. This socket will queue
       incoming connections. */
    listener = socket(PF_INET, SOCK_STREAM, IPPROTO_IP);
    if (listener < 0) {
        printf("Unable to create a listener socket: %s\n",
               strerror(errno));
        return 1;
    }

    /* Now bind the listener to a local address. This uses
       the same sockaddr_in structure as connect. */
    sa_len = sizeof(sa);
    memset(&sa, 0, sa_len);
    sa.sin_family = AF_INET;
    sa.sin_port = htons(port);
    sa.sin_addr.s_addr = htonl(INADDR_ANY); /* Listen on
                                               all interfaces. */

    if (bind(listener, (struct sockaddr *)&sa, sa_len) < 0) {
        printf("Unable to bind to port %i: %s\n",
               port,
               strerror(errno));
        return 1;
    }

    /* Let the networking system know we're accepting
       connections on this socket. Ask for a connection
       queue of five clients. (If more than five clients
       try to connect before we call accept, some will
       be denied.) */
    if (listen(listener, 5) < 0) {
        printf("Unable to listen: %s\n",
               strerror(errno));
        return 1;
    }

    /* Ready! Now accept connections until the user presses
       Ctrl-C. */
    signal(SIGINT, signal_handler);

    for (;;) {
        char sendbuf[1024];
        int sent, length;
        FILE *uptime;

        client = accept(listener, &sa, &sa_len);
        if (client < 0) {
            printf("Unable to accept: %s\n",
                   strerror(errno));
            close(listener);
            return 1;
        }

        /* We now have a live client. Print information
           about it and then send something over the wire. */
        inet_ntop(AF_INET, &sa.sin_addr, dotted_ip, 15);
        printf("Received connection from %s.\n", dotted_ip);

        /* Use popen to retrieve the output of the
           uptime command. This is a bit of a hack, but
           it's portable and it works fairly well.
           popen opens a pipe to a program (that is, it
           executes the program and redirects its I/O
           to a file handle). */
        uptime = popen("/usr/bin/uptime", "r");
        if (uptime == NULL) {
            strcpy(sendbuf, "Unable to read system's uptime.\n");
        } else {
            sendbuf[0] = '\0';
            fgets(sendbuf, 1023, uptime);
            pclose(uptime);
        }
                
        /* Figure out how much data we need to send. */
        length = strlen(sendbuf);
        sent = 0;

        /* Repeatedly call write until the entire
           buffer is sent. */
        while (sent < length) {
            int amt;

            amt = write(client, sendbuf+sent, length-sent);

            if (amt <= 0) {
                /* Zero-byte writes are OK if they
                   are caused by signals (EINTR).
                   Otherwise they mean the socket
                   has been closed. */
                if (errno == EINTR)
                    continue;
                else {
                    printf("Send error: %s\n",
                           strerror(errno));
                    break;
                }
            }

            /* Update our position by the number of
               bytes that were sent. */
            sent += amt;
        }

        close(client);
    }

    return 0;
}
\end{verbatim}
\end{codelisting}

Our server starts by creating a socket and binding it to a local port. It specifies \code{INADDR\_ANY} for an address, since we don't have any particular network interface in mind. (You could use this to bind the socket to just one particular IP address in a multihomed system, but games usually don't need to worry about this.) It then uses \code{listen} to set the socket up as a listener with a connection queue of five clients.

Next comes the accept loop, in which the server actually receives and processes incoming connections. It processes one client for each iteration of the loop. Each client gets a copy of the output of the Linux \cmdline{uptime} program. (Note the use of \code{popen} to create this pipe.) The server uses a simple \code{write} loop to send this data to the client.

If you feel adventurous, you might try modifying this program to deal with multiline output (for instance, the output of the \cmdline{netstat} program). 

\newpage
\begin{note}{Handling Multiple Clients}
Linux is a multitasking operating system, and it's easy to write programs that handle more than one client at a time. There are several ways to do this, but in my opinion the simplest is to create a separate thread for each client. (See the \code{pthread\_create} manpage.) Be careful, though---some sockets API functions are not thread-safe and shouldn't be called by more than one thread at a time.

If you're interested in learning how to write solid UNIX-based network servers, I suggest the book \othertitle{UNIX Network Programming} \cite{UNP98}. It was of great assistance as I wrote this chapter. Another useful reference is \othertitle{The Pocket Guide to TCP/IP Sockets} \cite{PSOCK01}, a much smaller and more concise treatment of the sockets API.
\end{note}

\index{TCP servers|)}

\section{Working with UDP Sockets}

\index{UDP (User Datagram Protocol)|(}
UDP is a connectionless protocol. While TCP can be compared to a telephone conversation, UDP is more like the postal service. It deals with individually addressed packets of information that are not part of a larger stream. UDP is great for blasting game updates across the network with reckless abandon. They probably won't all get there, but enough should arrive to keep the game running smoothly.

As we did with TCP, we'll demonstrate UDP with a sender and receiver. Here goes:

\begin{codelisting}{udpsender.c}{code:udpsender}
\begin{verbatim}
/* Simple UDP packet sender. */

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <sys/socket.h>

struct hostent *hostlist;   /* List of hosts returned
                               by gethostbyname. */
char dotted_ip[15];         /* Buffer for converting
                               the resolved address to
                               a readable format. */
int port;                   /* Port number. */
int sock;                   /* Our connection socket. */
struct sockaddr_in sa;      /* Connection address. */

int packets_sent = 0;

/* This function gets called whenever the user presses Ctrl-C.
   See the signal(2) manpage for more information. */
void signal_handler(int signum)
{
    switch (signum) {
    case SIGINT:
        printf("\nReceived interrupt signal. Exiting.\n");
        close(sock);
        exit(0);
                        
    default:
        printf("\nUnknown signal received. Ignoring.\n");
    }
}

int main(int argc, char *argv[])
{

    /* Make sure we received two arguments,
       a hostname and a port number. */
    if (argc < 3) {
        printf("Simple UDP datagram sender.\n");
        printf("Usage: %s <hostname or IP> <port>\n", argv[0]);
        return 1;
    }

    /* Look up the hostname with DNS. gethostbyname
       (at least most UNIX versions of it) properly
       handles dotted IP addresses as well as hostnames. */
    printf("Looking up %s...\n", argv[1]);
    hostlist = gethostbyname(argv[1]);
    if (hostlist == NULL) {
        printf("Unable to resolve %s.\n", argv[1]);
        return 1;
    }
        
    /* Good, we have an address. However, some sites
       are moving over to IPv6 (the newer version of
       IP), and we're not ready for it (since it uses
       a new address format). It's a good idea to check
       for this. */
    if (hostlist->h_addrtype != AF_INET) {
        printf("%s doesn't seem to be an IPv4 address.\n",
               argv[1]);
        return 1;
    }

    /* inet_ntop converts a 32-bit IP address to
       the dotted string notation (suitable for printing).
       hostlist->h_addr_list is an array of possible addresses
       (in case a name resolves to more than one IP). In most
       cases we just want the first. */
    inet_ntop(AF_INET, hostlist->h_addr_list[0], dotted_ip, 15);
    printf("Resolved %s to %s.\n", argv[1], dotted_ip);

    /* Create a SOCK_DGRAM socket. */
    sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
    if (sock < 0) {
        printf("Unable to create a socket: %s\n",
               strerror(errno));
        return 1;
    }

    /* Fill in the sockaddr_in structure. The address is already
       in network byte order (from the gethostbyname call).
       We need to convert the port number with the htons macro.
       Before we do anything else, we'll zero out the entire
       structure. */
    memset(&sa, 0, sizeof(struct sockaddr_in));

    port = atoi(argv[2]);
    sa.sin_port = htons(port);
        
    /* The IP address was returned as a char * for various reasons.
       Just memcpy it into the sockaddr_in structure. */
    memcpy(&sa.sin_addr, hostlist->h_addr_list[0],
           hostlist->h_length);
        
    /* This is an Internet socket. */
    sa.sin_family = AF_INET;

    printf("Sending UDP packets. Press Ctrl-C to exit.\n");
        
    /* Install a signal handler for Ctrl-C (SIGINT).
       See the signal(2) manpage for more information. */
    signal(SIGINT, signal_handler);

    /* Send packets at 1s intervals until the user pressed Ctrl-C. */
    for (;;) {

        char message[255];

        sprintf(message, "Greetings! This is packet %i.", packets_sent);

        /* Send a packet containing the above string.
           This could just as easily be binary data,
           like a game update packet. */
        if (sendto(sock,              /* initialized UDP socket */
                   message,           /* data to send */
                   strlen(message)+1, /* msg length + trailing NULL */
                   0,                 /* no special flags */
                   &sa,               /* destination */
                   sizeof(struct sockaddr_in)) <= (int)strlen(message)) {
            printf("Error sending packet: %s\n",
                   strerror(errno));
            close(sock);
            return 1;
        }

        printf("Sent packet.\n");


        /* To observe packet loss, remove the following
           sleep call. Warning: this WILL flood the network. */
        sleep(1);

        packets_sent++;
    }

    /* This will never be reached. */
    return 0;
}
\end{verbatim}
\end{codelisting}

This program starts out very much like the TCP client. It looks up the remote system's IP address with DNS, prepares an address structure, and creates a socket. However, it never calls \code{connect}. The address structure is like an address stamp that UDP slaps onto each outgoing packet. This example uses the \code{sendto} function to send data over UDP. There are other ways to go about it, but \code{sendto} is the most common. It takes an initialized UDP socket, a buffer of data, and a valid address structure. \code{sendto} attempts to compose a UDP packet and send it on its way across the network. Since this is UDP, there is no guarantee as to whether or not this packet will actually be sent.

\begin{apiref}
\apifunction{sendto(sock, buf, length, flags, addr, addr\_len)}
\apisynopsis{Sends a UDP datagram to the specified address.}
\apireturns{Number of bytes sent, or $-1$ on error. There is no guarantee that the message will actually be sent (though it's likely).}
\apifirstparm{sock}{Initialized \code{SOCK\_DGRAM} socket.}
\apinextparm{buf}{Buffer of data to send.}
\apinextparm{length}{Size of the buffer. This is subject to system-dependent size limits.}
\apinextparm{flags}{Message flags. Unless you have a specific reason to use a flag, this should be zero.}
\apinextparm{addr}{\code{sockaddr\_in} address structure that specifies the message's destination.}
\apinextparm{addr\_len}{Size of the address structure. \code{sizeof (addr)} should work.}
\apiendparms
\end{apiref}

If you want to test out your network's capacity (or just irritate the sysadmin), take the \code{sleep} call out of the sender program. This will make the program fire off packets as quickly as possible. It's not a good idea to do this in a game---it would be wise to limit the transmission speed so that other applications can coexist with your game on the network. (I tried this, and my network hub lit up like a Christmas tree.)

And now the receiver:

\begin{codelisting}{udpreceiver.c}{code:udpreceiver.c}
\begin{verbatim}
/* Simple UDP packet receiver. */

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <sys/socket.h>

int port;                   /* Port number. */
int sock;                   /* Our connection socket. */
struct sockaddr_in sa;      /* Connection address. */
socklen_t sa_len;           /* Size of sa. */

/* This function gets called whenever the user presses Ctrl-C.
   See the signal(2) manpage for more information. */
void signal_handler(int signum)
{
    switch (signum) {
    case SIGINT:
        printf("\nReceived interrupt signal. Exiting.\n");
        close(sock);
        exit(0);
                        
    default:
        printf("\nUnknown signal received. Ignoring.\n");
    }
}

int main(int argc, char *argv[])
{

    /* Make sure we received one argument,
       the port number to listen on. */
    if (argc < 2) {
        printf("Simple UDP datagram receiver.\n");
        printf("Usage: %s <port>\n", argv[0]);
        return 1;
    }

    /* Create a SOCK_DGRAM socket. */
    sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
    if (sock < 0) {
        printf("Unable to create a socket: %s\n",
               strerror(errno));
        return 1;
    }

    /* Fill in the sockaddr_in structure. The address is already
       in network byte order (from the gethostbyname call).
       We need to convert the port number with the htons macro.
       Before we do anything else, we'll zero out the entire
       structure. */
    memset(&sa, 0, sizeof(struct sockaddr_in));

    port = atoi(argv[1]);
    sa.sin_port = htons(port);
    sa.sin_addr.s_addr = htonl(INADDR_ANY);  /* listen on
                                                all interfaces */
        
    /* This is an Internet socket. */
    sa.sin_family = AF_INET;

    /* Bind to a port so the networking software will know
       which port we're interested in receiving packets from. */
    if (bind(sock, (struct sockaddr *)&sa, sizeof(sa)) < 0) {
        printf("Error binding to port %i: %s\n",
               port,
               strerror(errno));
        return 1;
    }

    printf("Listening for UDP packets. Press Ctrl-C to exit.\n");
        
    /* Install a signal handler for Ctrl-C (SIGINT).
       See the signal(2) manpage for more information. */
    signal(SIGINT, signal_handler);

    /* Collect packets until the user pressed Ctrl-C. */
    for (;;) {

        char buf[255];

        /* Receive the next datagram. */
        if (recvfrom(sock,      /* UDP socket */
                     buf,       /* receive buffer */
                     255,       /* max bytes to receive */
                     0,         /* no special flags */
                     &sa,       /* sender's address */
                     &sa_len) < 0) {
            printf("Error receiving packet: %s\n",
                   strerror(errno));
            return 1;
        }

        /* Announce that we've received something. */
        printf("Got message: '%s'\n", buf);
    }

    /* This will never be reached. */
    return 0;
}
\end{verbatim}
\end{codelisting}

The UDP receiver program starts up much like our TCP server, except that it doesn't call \code{listen} or \code{accept} (since UDP is, of course, connectionless). After binding to a local port, the program calls \code{recvfrom} to retrieve datagrams. Datagrams are individual packages; you have to receive them either all at once or not at all (unlike TCP, which provides a stream of bytes that you can pick off one at a time). \code{recvfrom} is a blocking call; it will wait until a datagram arrives before it returns.

\begin{apiref}
\apifunction{recvfrom(sock, buf, length, flags, addr, addr\_len)}
\apisynopsis{Receives a UDP datagram from a local port.}
\apireturns{Number of bytes received, or $-1$ on error.}
\apifirstparm{sock}{Initialized \code{SOCK\_DGRAM} socket that has been associated with a local port with \code{bind}.}
\apinextparm{buf}{Buffer to receive incoming data.}
\apinextparm{length}{Maximum number of bytes to receive.}
\apinextparm{flags}{Message flags. Unless you have a specific reason to use a flag, this should be zero.}
\apinextparm{addr}{\code{sockaddr\_in} address structure to receive information about the sender of the message.}
\apinextparm{addr\_len}{Size of the address structure. \code{sizeof (addr)} should work.}
\apiendparms
\end{apiref}

That's it for UDP! Now it's time to apply this stuff (TCP at least) to \gametitle{Penguin Warrior}.

\index{UDP (User Datagram Protocol)|)}
\index{sockets|)}

\section{Multiplayer Penguin Warrior}

So far, \gametitle{Penguin Warrior} has supported only a computer-controlled opponent, and a fairly unintelligent one at that. However, it's a lot more fun to play against humans than against Tcl scripts.

This will be a simple networking system, as games go. It will use a simple TCP scheme to keep the game in sync, and it will not make use of UDP. (That would be overkill for a game like \gametitle{Penguin Warrior}.) It will trust that the clients are secure (that is, that they have not been hacked for the purpose of cheating). Nonetheless, it should give you an idea of what goes into a network-ready game.

\subsection{Network Gaming Models}
\label{sect:netmodels}
\index{network gaming models|(}

The ultimate goal of a networked game is to allow two or more players to participate in a single game universe at the same time. Whether they are competing against each other or cooperating in a battle against other opponents is of little consequence. All networkable games need to solve the same basic problem of keeping the players informed about the state of the running game. Here are some of the more common approaches to this problem:

\begin{bodylist}
\item [Client/server] Each player uses a local copy of the game (a \firstterm{client}) to connect to a single central machine (the \firstterm{game server} or \firstterm{dedicated server}) that knows the game's rules and serves as a master authority on the game's state. Clients send updates to the server, and the server sends authoritative updates back to each client. In this model, the server is always right. It is very difficult to cheat in a client/server gaming situation, because every client talks to the same server, and the server applies the same rules to everyone. This is the most common setup for major online games.

\item [Peer-to-peer] This approach is good for small games like \gametitle{Penguin Warrior}. Each player's computer maintains a local copy of the game's state and informs all of the other computers whenever anything changes. The main problem with this system is that it is very easy for players to cheat by modifying their local copies of the game. There is no centralized ``referee'' in peer-to-peer multiplayer games.

\item [Client is a server] In some cases it is convenient to build the game server code into the game itself, so that any player with a fast computer and a reasonably fast network connection can ``host'' a multiplayer game for friends. This method is a little less prone to cheating than the peer-to-peer model, but an untrustworthy player could covertly modify the server to gain an advantage.
\end{bodylist}

It is fallacious to think that closed source binary games are immune to cheaters; \gametitle{Ultima Online} and \gametitle{Diablo} are evidence to the contrary. Any sufficiently idle 3r33t h@x0ring d00d with a hex editor can have a field day with these games. If you are concerned about possible cheating, the only real solution is to use a design that enforces equality between the players. (\gametitle{Penguin Warrior} does not use such a design; it would be trivial to cheat in a multiplayer game.)

\extfigure{figures/network-models}{fig:networkmodels}{Three ways to set up a network game}

\index{network gaming models|)}

\subsection{Penguin Warrior's Networking System}
In the interest of simplicity, \gametitle{Penguin Warrior} will use the peer-to-peer model. One copy of the game will act as a TCP server, and the other will connect as a TCP client. It does not matter which role goes to which player; the players are completely equal after the link is established. Once the two players are linked, they will begin to exchange update packets with one another. Each update packet will contain the world coordinates of the player that sent it (in other words, it says, ``I'm at this position; now reply with your position''). The players will send these packets back and forth as quickly as possible (with a small speed brake to keep from flooding the network). The game will end when the connection is broken (that is, when one of the players exits the game). It's simple, but it should work well given a reasonably fast network (not a modem connection).

\begin{note}{Source Files}
The \gametitle{Penguin Warrior} networking system consists of \filename{network.c}, \filename{network.h}, and some heavy modifications to \filename{main.c}. You can find this chapter's code in the \filename{pw-ch7/} directory of the book's source archive. No additional libraries are needed for networking support; that's built into the operating system.
\end{note}

What happens when a player fires or gets hit by a shot? Update packets also contain fields for this information. Whenever a player fires, the networking system sends a packet with the ``fire'' flag set. The other player should then display an appropriate moving projectile. Players keep track of their own projectiles; if you press the fire button and launch a volley at your opponent, your copy of \gametitle{Penguin Warrior} is responsible for tracking the projectiles to their respective destinations.\footnote{Weapons are not actually present in this version of the game. We'll add them in Chapter \ref{ch:finishingpw}. Our protocol for handling weapons is in place, though.} If your copy of the game decides that the other player has been hit, it sends this information in the next outgoing network packet.

For reference, here's the \gametitle{Penguin Warrior} update packet structure:

\begin{codesegment}
\begin{verbatim}
typedef struct net_pkt_s {
    Sint32 my_x, my_y;
    Sint32 my_angle;
    Sint32 my_velocity;
    Uint8 fire;
    Uint8 hit;
} net_pkt_t, *net_pkt_p;
\end{verbatim}
\end{codesegment}

There's not much to it (which is good, since this structure is sent over the wire many times each second). Note that the values are sent as \code{Sint32} (the SDL signed 32-bit integer type) instead of \code{double} (which the game uses internally). The exact meaning and encoding of \code{double} can vary between platforms. It \emph{probably} won't (it's a standard IEEE double-precision floating-point number on most platforms), but Murphy's Law indicates that we shouldn't take anything for granted. By applying a simple network encoding formula (given by macros in \filename{network.h}), we ensure that our coordinates will always reach the other end intact, regardless of the CPU types involved.

\begin{warning}
You can often ignore endianness issues when you're writing a single-player game or coding for a particular type of machine, but unlike Microsoft's flagship products, Linux is not limited to the arcane x86 CPU architecture. If there's any possibility at all that your networked game or application will need to exchange data with another type of system (for instance, a multiplayer game between a PC and an UltraSPARC), it's important to watch out for endianness and other encoding issues. Never assume that basic datatypes will be exactly the same on any two platforms. The sockets API can help with its network byte order macros, and SDL provides similar macros for ensuring a particular endianness.
\end{warning}

Coding time! Here's \filename{network.c}, which implements the basic two-player protocol over TCP.

\begin{codelisting}{network.c}{code:pwnetwork}
\begin{verbatim}
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <string.h>
#include <errno.h>
#include <netdb.h>
#include "network.h"

void CreateNetPacket(net_pkt_p pkt, player_p player,
                     int firing, int hit)
{

    /* Fill in all of the relevant values, calling
       our conversion macro to preclude endianness
       problems. */
    pkt->my_x = DOUBLE_TO_NET(player->world_x);
    pkt->my_y = DOUBLE_TO_NET(player->world_y);
    pkt->my_angle = DOUBLE_TO_NET(player->angle);
    pkt->my_velocity = DOUBLE_TO_NET(player->velocity);
    pkt->fire = (Uint8)firing;
    pkt->hit = (Uint8)hit;
}

void InterpretNetPacket(net_pkt_p pkt,
                        double *remote_x, double *remote_y,
                        double *remote_angle,
                        double *remote_velocity,
                        int *firing, int *hit)
{
    /* Decode the values in the packet and store
       them in the appropriate places. */
    *remote_x = NET_TO_DOUBLE(pkt->my_x);
    *remote_y = NET_TO_DOUBLE(pkt->my_y);
    *remote_angle = NET_TO_DOUBLE(pkt->my_angle);
    *remote_velocity = NET_TO_DOUBLE(pkt->my_velocity);
    *firing = (int)pkt->fire;
    *hit = (int)pkt->hit;
}

int ConnectToNetgame(char *hostname, int port, net_link_p link)
{
    int sock;
    struct sockaddr_in addr;
    struct hostent *hostlist;


    /* Resolve the host's address with DNS. */
    hostlist = gethostbyname(hostname);
    if (hostlist == NULL || hostlist->h_addrtype != AF_INET) {
        fprintf(stderr, "Unable to resolve %s: %s\n",
                hostname,
                strerror(errno));
        return -1;
    }
        
    /* Save the dotted IP address in the link structure. */
    inet_ntop(AF_INET, hostlist->h_addr_list[0],
              link->dotted_ip, 15);

    /* Load the address structure with the server's info. */
    memset(&addr, 0, sizeof (struct sockaddr_in));
    addr.sin_family = AF_INET;
    memcpy(&addr.sin_addr, hostlist->h_addr_list[0],
           hostlist->h_length);
    addr.sin_port = htons(port);

    /* Create a TCP stream socket. */
    sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (sock < 0) {
        fprintf(stderr, "Unable to create socket: %s\n",
                strerror(errno));
        return -1;
    }
        
    printf("Attempting to connect to %s:%i...\n",
           link->dotted_ip, port);

    /* Ready to go! Connect to the remote machine. */
    if (connect(sock, (struct sockaddr *)&addr,
        sizeof (addr)) < 0) {
        fprintf(stderr, "Unable to connect: %s\n",
                strerror(errno));
        close(sock);
        return -1;
    }

    /* Copy the socket and the address into the link structure. */
    link->sock = sock;
    link->addr = addr;

    printf("Connected!\n");

    return 0;
}

int WaitNetgameConnection(int port, net_link_p link)
{
    int listener, sock;
    struct sockaddr_in addr;
    socklen_t addr_len;

    /* Create a listening socket. */
    listener = socket(PF_INET, SOCK_STREAM, IPPROTO_IP);
    if (listener < 0) {
        fprintf(stderr, "Unable to create socket: %s\n",
                strerror(errno));
        return -1;
    }

    /* Set up the address structure for the listener. */
    addr_len = sizeof (addr);
    memset(&addr, 0, addr_len);
    addr.sin_family = AF_INET;
    addr.sin_port = htons(port);
    addr.sin_addr.s_addr = htonl(INADDR_ANY);

    /* Bind the listener to a local port. */
    if (bind(listener, &addr, addr_len) < 0) {
        fprintf(stderr, "Unable to bind to port %i: %s\n",
                port, strerror(errno));
        close(listener);
        return -1;
    }

    /* Make this a listening socket. */
    if (listen(listener, 1) < 0) {
        fprintf(stderr, "Unable to listen: %s\n",
                strerror(errno));
        close(listener);
        return -1;
    }

    printf("Waiting for connection on port %i.\n", port);

    /* Accept a connection. */
    if ((sock = accept(listener, (struct sockaddr *)&addr,
        &addr_len)) < 0) {
        fprintf(stderr, "Unable to accept connection: %s\n",
                strerror(errno));
        close(listener);
        return -1;
    }

    /* Ready to go! Save this info in the link structure. */
    link->sock = sock;
    link->addr = addr;
    inet_ntop(AF_INET, &addr.sin_addr, link->dotted_ip, 15);        

    printf("Connected!\n");

    return 0;
}

int ReadNetgamePacket(net_link_p link, net_pkt_p pkt)
{
    int remaining, count;

    remaining = sizeof (struct net_pkt_s);
    count = 0;

    /* Loop until a complete packet arrives.
       This could block indefinitely, but it
       typically won't, and it's of less importance
       since the networking code runs in a separate
       thread. */
    while (remaining > 0) {
        int amt;

        /* Read as much as possible. */
        amt = read(link->sock, ((char *)pkt)+count, remaining);

        /* If read returns a positive value, or zero
           with errno == EINTR, there is no error. */
        if (amt <= 0 && errno != EINTR) {
            fprintf(stderr, "ReadNetgamePacket: read failed: %s\n",
                    strerror(errno));
            return -1;
        }
                
        /* Increment the counters by the amount read. */
        remaining -= amt;
        count += amt;
    }
      
    return 0;
}

int WriteNetgamePacket(net_link_p link, net_pkt_p pkt)
{
    int remaining, count;

    remaining = sizeof (struct net_pkt_s);
    count = 0;

    /* Loop until we've written the entire packet. */
    while (remaining > 0) {
        int amt;

        /* Try to write the rest of the packet.
           Note the amount that was actually written. */
        amt = write(link->sock, ((char *)pkt)+count, remaining);

        /* Same error semantics as ReadNetgamePacket. */
        if (amt <= 0 && errno != EINTR) {
            fprintf(stderr, "WriteNetgamePacket: read failed: %s\n",
                    strerror(errno));
            return -1;
        }
                
        /* Increments the counters by the number of
           bytes written. */
        remaining -= amt;
        count += amt;
    }
      
    return 0;
}

void CloseNetgameLink(net_link_p link)
{

    /* Close the socket connection. */
    close(link->sock);
    link->sock = -1;
}
\end{verbatim}
\end{codelisting}

The first two functions, \code{CreateNetPacket} and \code{InterpretNetPacket}, help us deal with network packets. We can pretty much be as sloppy as we want about our internal game state variables, but organization is very important when we're communicating with another program at a high speed over network. These functions convert between a game's state and network packet structures so that our main code doesn't need to worry about the ``wire format'' of the data.

\code{ConnectToNetgame} tries to connect to another copy of \gametitle{Penguin Warrior} over the network. After resolving the remote system's IP address with DNS, it attempts a normal TCP socket connection and stores the connected socket in the provided \code{net\_link\_t} structure. \gametitle{Penguin Warrior} performs no synchronization or negotiation; it assumes that whatever answers the connection request is a copy of \gametitle{Penguin Warrior} that speaks the same protocol. It would be a simple matter to exchange some small piece of data over the link to make sure of this before starting the game.

The next function, \code{WaitNetgameConnection}, waits for a copy of \gametitle{Penguin Warrior} to connect on a given port number. This is the counterpart of \code{ConnectToNetgame}. It consists of simple TCP server code that we've already discussed. It is important to realize that this is not a client/server game; the ``server'' is called that only because it waits for another player, the ``client,'' to connect. After the connection, there is no difference between the two sides of the connection.

\code{ReadNetgamePacket} and \code{WriteNetgamePacket} send and receive complete game update packets over the network. We could probably get away with using simple \code{read} or \code{write} calls, but there's no guarantee that either of these calls will process the full amount of data requested. To handle this, \code{ReadNetgamePacket} and \code{WriteNetgamePacket} keep track of the amount of data transferred and loop until a complete packet has been processed. It would be simple to adapt these routines into general-purpose socket reading and writing utilities.

\longpage
Finally, \code{CloseNetgameLink} closes a multiplayer game link. It uses the normal \code{close} function to shut down the socket. The TCP/IP protocol handles this without further interaction.

That's it for the networking code. Everything else is in \filename{main.c}. We won't reprint it here, since it would be largely redundant, but it's worth taking a look at to see the changes. We've added \code{UpdateNetworkPlayer} to send and receive update packets and a new thread (launched with \code{NetworkThread}) to run the networking in the background (so that the speed of our main loop isn't limited by the latency of the network). Note also that the player data structures are now protected by a mutex so that the network thread and the main loop can safely access them without bumping into each other.

\section{Network Game Performance}

Anyone who's ever played a multiplayer action game has probably felt the frustration of lining up for a kill and having the game suddenly slow to an unplayable crawl. The Internet is enormous, and its performance range is anywhere from solid to flaky. Multiplayer games unfortunately require a very high level of sustained performance, and it's left to the game developer to make ends meet in this turbulent medium. In this section we'll make some observations about network performance and suggest ways to squeeze acceptable performance out of the Internet.

Gamers often grumble about slow network performance. Two primary factors play into this problem. \index{packet loss}\firstterm{Packet loss} is the tendency of overloaded or unreliable networks to lose information at random. We've already mentioned this with respect to UDP---if you send a UDP packet across the network, it might get there, and it might not. TCP detects and corrects missing packets, but they throw a monkey wrench into the communication process and kill performance. There's not a lot you can do to prevent packet loss, unless you intend to install your own high-speed communication lines; you can only minimize its effects on your games. The most common way of dealing with packet loss is simply to ignore it. TCP holds up the transmission pipeline until packets arrive at the other end intact, at which point it's probably past time to send the next update anyway. (In this case, error correction actually hurts game performance.) UDP does not have this problem.

Another culprit of lousy network performance is \index{latency}\firstterm{latency}, the time it takes a given piece of information to travel across the network. Latency depends both on the speed of the underlying network and on its current traffic load. Unless your game uses prediction or another clever strategy, players will always be out of sync by the amount of time it takes them to exchange network packets. A reasonable average latency for Internet games on fast connections is 100 milliseconds (ms), and any game should be able to handle this amount. However, the average latency can easily rise to the vicinity of 500 to 1000 ms if slow network devices (modems) are involved, and at this level it can become quite distracting. (For instance, a player might fire a weapon and see the effects a full second later.) Some games use statistics to guess what the other players will do during the next update interval, which can make a multiplayer game much smoother. Prediction would be overkill for something like \gametitle{Penguin Warrior}, but \gametitle{Quake} and \gametitle{Half-Life} make heavy use of this technique.

\section{Security Issues}

\index{network game security|(}
For some reason, many players get a thrill out of disrupting the normal course of a game for others. Players of \gametitle{Diablo} and \gametitle{Ultima Online} have access to any number of programs that mess with the underlying game code to give them an unfair advantage. Fans of the \gametitle{Half-Life} multiplayer modification \gametitle{Counter-Strike} constantly run into ``skin cheaters'' who modify their player models to make themselves invisible or make their enemies easier to spot. Cheating is an unfortunate part of online gaming. There are a lot of smart people out there who get a kick out of gaining an unfair advantage in the games they play. As if this weren't bad enough, these people often make their cheats available to their friends, and the problem grows exponentially. Although no game is perfectly secure against the determined cheater, good design can make cheating very difficult.

The problem is pretty simple, actually. Most major online games use a client/server model (see page \pageref{sect:netmodels}). Client/server games should theoretically do all of the game world's processing and error checking on the server side, leaving nothing important to the clients. If this were always the case, hacked clients would be of no consequence, and games like \gametitle{Half-Life} would be free of cheaters.

For basic performance reasons, however, very few games actually work this way. If a client had to run everything through the server, performance would be abysmal. Most games at least let the client do a bit of preloading, prediction, or collision detection. This work stays hidden from the player, unless someone hacks the program to make unfair use of this information. This is exactly what happened to \gametitle{Quake} when id Software released its source code. \gametitle{Quake} placed a bit too much trust in the game client, and unscrupulous gamers were quick to take advantage of this.

The only way to get around this problem is to make sure that any responsibilities assigned to a client can be verified by the server and to limit the amount of information the client gets about the state of the game. Players can and will figure out how to modify a game to report false update information or to misuse the information it receives. In a world of hex editors, protocol sniffers, and bored college students like myself, no game is safe from modification. Plan on it, and make sure it can't hurt anything.

\index{network game security|)}

We'll now put \gametitle{Penguin Warrior} on hold for a little while so we can hack some framebuffer console code. We'll pick the game back up in Chapter \ref{ch:finishingpw} and add all of the goodies it's missing, including weapons, player-to-player chat, and score counters. We'll also combine the code from chapters \ref{ch:linuxaudio}, \ref{ch:gamescripting}, and this chapter into a final version with all of the subsystems present. By the end of Chapter \ref{ch:finishingpw}, \gametitle{Penguin Warrior} will be a fully operational Linux game.
