Chapter 1. Introduction


The client and server organization is used by most network-awared applications. Some complex applications also require asynchronous callback communication, where the server initiates a message to the client.

unp.h header

A Simple Daytime Client


Create TCP socket

The socket function creates an Internet (AF_INET) stream (SOCK_STREAM) socket, which is a fancy name for a TCP socket. The function returns a small integer descriptor to identify the socket.

Specify server's IP address and port

The IP address (sin_addr) and port number (sin_port) fields in the Internet socket address structure (sockaddr_in) must be in specific formats:

bzero is not an ANSI C function, but is used in this book instead of the ANSI C memset function, because bzero is easier to remember (with only two arguments) than memset (with three arguments).

Establish connection with server

In the unp.h header, SA is defined to be struct sockaddr, a generic socket address structure.

Read and display server's reply

We must be careful when using TCP because it is a byte-stream protocol with no record boundaries. Since we cannot assume that the server's reply will be returned by a single read, we always need to code the read in a loop when reading from a TCP socket.

Terminate program

exit terminates the program. Unix always closes all open descriptors when a process terminates.

Protocol Independence

The above program is protocol-depdent on IPv4.

It is better to make a program protocol-independent by using the getaddrinfo function.

Error Handling: Wrapper Functions

We can shorten our programs by defining a wrapper function that performs the actual function call, tests the return value, and terminates on an error.

sockfd = Socket(AF_INET, SOCK_STREAM, 0);

With careful C coding, we could use macros instead of functions, providing a little run-time efficiency, but these wrapper functions are rarely the performance bottleneck of a program. This book uses these wrapper functions unless otherwise explicit error needs handling.

Unix errno Value

The value of errno is set by a function only if an error occurs. All of the positive error values are constants with all-uppercase names beginning with "E," and are normally defined in the <sys/errno.h> header. No error has a value of 0.

Storing errno in a global variable does not work with multiple threads that share all global variables.

A Simple Daytime Server


Create a TCP socket

Identical to the client code.

Bind server's well-known port to socket

Convert socket to listening socket

Accept client connection, send reply

This book uses this code style for infinite loop:

for ( ; ; ) {
    // . . .

snprintf function


Terminate connection

close initiates the normal TCP connection termination sequence: a FIN is sent in each direction and each FIN is acknowledged by the other end.

The server implemented in the above server code is:

OSI Model

Some terms mentioned:

Sockets provide the interface from the upper three layers of the OSI model into the transport layer:

BSD Networking History

Linux does not fit into the Berkeley-derived classification: Its networking code and sockets API were developed from scratch.

Unix Standards

Background on POSIX

Background on The Open Group

Internet Engineering Task Force (IETF)

64-Bit Architectures

From a programming perspective, the LP64 model means we cannot assume that a pointer can be stored in an integer. We must also consider the effect of the LP64 model on existing APIs

On a 32-bit system, size_t is a 32-bit value, but on a 64-bit system, it must be a 64-bit value, to take advantage of the larger addressing model. This means a 64-bit system will probably contain a typedef of size_t to be an unsigned long.