Add Book to My BookshelfPurchase This Book Online

Chapter 14 - Networking with Sockets

UNIX Systems Programming for SVR4
David A. Curry
 Copyright © 1996 O'Reilly & Associates, Inc.

Server-Side Functions
The server process needs to call each of these functions, in order, if it is to exchange data with a client.
Naming a Socket
After creating a socket, a server process must provide that socket with a name by which client programs can access it. The function to assign a name to a socket is called bind:
    #include <sys/types.h>
    #include <sys/socket.h>
    int bind(int s, const struct sockaddr *name, int addrlen);
After completion of bind, the communications channel referenced by the socket descriptor s will have the address described by name. In order for bind to succeed, the address must not already be in use. Because name may be of different sizes depending on the address family being used, addrlen is used to indicate its length. If bind succeeds, it returns 0. If it fails (often because the address is already in use), it returns -1 and stores an error code in errno.
In the Internet domain, the name parameter is of type struct sockaddr_in, defined in the include file netinet/in.h:
    struct sockaddr_in {
        short             sin_family;
        u_short           sin_port;
        struct in_addr    sin_addr;
    };
The sin_family element is always set to AF_INET, identifying this address as being in the Internet domain. The sin_port element contains the port number associated with this socket. The sin_addr element contains the host address associated with the port.
When writing server processes, remember that the host on which the process is running may have more than one network interface and, therefore, more than one network address. To handle this, you can create more than one socket and bind a name to each socket, using the same value for sin_port, and different values for sin_addr, for each socket. An easier way is to use the wildcard address INADDR_ANY in the sin_addr element; this will allow a single socket to receive data from all network interfaces.
Waiting for Connections
If a server is providing a service via a stream-based socket, it must notify the operating system when it is ready to accept connections from clients on that socket. To do this, it uses the listen function:
    #include <sys/types.h>
    #include <sys/socket.h>
    int listen(int s, int backlog);
This function tells the operating system that the server is ready to accept connections on the socket referenced by s. The backlog parameter specifies the number of connection requests that may be pending at any given time; most operating systems silently limit this to a maximum of five. If a connection request arrives when the queue of pending connections is full, the client will receive a “connection refused” error.
Accepting Connections
To accept a connection, the server uses the accept function:
    #include <sys/types.h>
    #include <sys/socket.h>
    int accept(int s, struct sockaddr *name, int *addrlen);
When a connection request arrives on the socket referenced by s, accept returns a new socket descriptor. The server can use this new descriptor to communicate with the client; the old descriptor (the one bound to the well-known address) may continue to be used for accepting additional connections. When the connection is accepted, if name is not null the operating system stores the address of the client there, and will store the length of the address in addrlen. If accept fails, it returns -1 and places the reason for failure in errno.

Previous SectionNext Section
Books24x7.com, Inc © 2000 –  Feedback