Before you create a connection, establish the correct variables and collect
the information that you need to request a connection.
Your server process needs to:
Declare socket address
variables.
Assign a wildcard
address.
Get the port address of the service that you want to provide.
Your client process needs to:
Declare socket address
variables.
Get the remote host's internet address.
Get the port address
for the service that you want to use.
These activities are described next. Refer to the program
example at the end of this chapter to see how these activities work
together.
Declaring Socket Address Variables |
 |
You need to declare a variable of type struct sockaddr_in
to use for socket addresses. For example, the following declarations
are used in the example client program:
struct sockaddr_in myaddr; /* for local socket address */ struct sockaddr_in peeraddr; /* for peer socket address */
|
sockaddr_in is a special
case of sockaddr and is used with
the AF_INET addressing
domain.
Both types are shown in this chapter, but sockaddr_in
makes it easier to manipulate the internet and port addresses. Some
of the BSD Sockets system calls are declared using a pointer to
sockaddr, but you can also use
a pointer to sockaddr_in.
The sockaddr_in address structure
consists of the following fields:
The server process only needs an address for its own socket.
Your client process may not need an address for its local socket.
Refer to the inet(7f) man page
for more information on sockaddr_in.
Getting the Remote Host's Internet Address |
 |
gethostbyname obtains the
internet address of the host
and the length of that address (as the size of struct in_addr)
from /etc/hosts
or from NIS name server. gethostbyname
and its parameters are described in the following table.
- Include files:
- System call:
struct hostent *gethostbyname(name) char *name;
|
- Function result:
pointer to struct hostent
containing internet address NULL pointer (0) if failure occurs.
Example:
#include <netdb.h> struct hostent *hp; /* pointer to host info for remote host */ ... peeraddr.sin_family = AF_INET; hp = gethostbyname (argv[1]); peeraddr_in.sin_addr.s_addr = ((struct in_addr *)(hp->h_addr))->s_addr; |
The argv[1] parameter is
the host name specified in the client program command line. Refer
to the gethostent(3n) man page
for more information on gethostbyname.
Getting the Port Address for the Desired Service |
 |
When a server process is preparing to offer a service, it
must get the port address for the service from /etc/services
so it can bind that address to its "listen" socket.
If the service is not already in /etc/services,
you must add it.
When a client process needs to use a service that is offered
by some server process, it must request a connection to that server
process's "listening" socket. The client process
must know the port address for that socket.
getservbyname obtains the
port address of the specified service from /etc/services. getservbyname
and its parameters are described in the following table.
- Include files:
- System call:
struct servent *getservbyname(name, proto) char *name, *proto;
|
- Function result:
pointer to struct servent
containing port address NULL, pointer (0) if failure occurs.
Example:
#include <netdb.h> struct servent *sp; /* pointer to service info */ ... sp = getservbyname ("example", "tcp"); peeraddr.sin_port = sp->s_port;
|
When to Get the Server's Socket Address
The server process needs to get the socket address before
binding the listen socket. The client process needs to get the socket
address before the client executes a connection request. Refer to
the getservent(3n) man page for
more information on getservbyname.
Using a Wildcard Local Address |
 |
Wildcard
addressing
simplifies local
address binding. When an address is assigned the value of INADDR_ANY,
the host interprets the address as any valid address. This is useful
for your server process when you are setting up the listen socket.
It means that the server process does not have to look up its own
internet address. When INADDR_ANY is used as a host address, it
also allows the server to listen to all network connections on the
host. When a specific address is used in the bind, the server can
only listen to that specific connection. Thus, INADDR_ANY is useful
on a system in which multiple LAN cards are available, and messages
for a given socket can come in on any of them.
For example, to bind a specific port address to a socket,
but leave the local internet address unspecified, the following
source code could be used:
#include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> ... struct sockaddr_in sin; ... s = socket(AF_INET, SOCK_STREAM, 0); sin.sin_family = AF_INET; sin.sin_addr.s_addr = INADDR_ANY; sin.sin_port = MYPORT; bind (s, &sin, sizeof(sin));
|