/*______
This program creates a well-known Internet domain socket. Each time it accepts a connection, it forks
a child to print out a message from the client. It then goes on to accept new connections. The child
executes the procedure recho. To run this Echo Serverprogram:
––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––*/
#include <sys/types.h
#include <sys/socket.h
#include <netinet/in.h
#include <stdio.h
main()
{
/*______
Declare a local socket structure of the type "Internet socket address structure" named sockaddr_in,
which is defined by including the netineet/in.h header.
––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––*/
structsockaddr_in local;
/*______
Declare integers to store returned socket descriptors. The variable len stores the length of the socket.
––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––*/
intsk, rsk, len=sizeof(local);
/*______
The socket function creates an Internet (AF_INET) stream socket (SOCK_STREAM0, and we select a
TCP to be the default protocol by setting the last argument to 0. The function returns a small integer
descriptor which we can use to identify the socket in all future function calls, namely the calls to
connect with the server and read from the server.
––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––*/
sk=socket(AF_INET,SOCK_STREAM,0);
/*______
In the following, we construct and bind the Internet socket address structure. We first specify the
address family to AF_INET. We then specify the IP address to INADDR_ANY, which allows the server to
accept a client connection on any interface, in case the server has multiple interfaces. (It is always
possible to restrict the server to accept connections on a specific interface.). Since this is not a well-
known server, we request the system to assign an "ephemral" port number. In doing so, we ensure
that no port number collision occurs with an existence user-level application. To request a port
number, we set the port field of the structure to 0. Upon filling the Internet socket address structure,
the server's port number is bound to the socket by calling bind().
––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––*/
local.sin_family=AF_INET;
local.sin_addr.s_addr=INADDR_ANY;
local.sin_port=0;
bind(sk, (structsockaddr *) &local, sizeof(local));
/*______
To find out what port number has been assigned to the socket, we call getsockname(). The
getsockname() function has the following syntax:
- intgetsockname(int socket, structsockaddr *address, socklen_t *address_len);
When called, the function retrieves the locally-bound name of the specified socket, stores this address
in the sockaddr structure pointed to by the address argument, and stores the length of this address in
the object pointed to by the address_len argument.
––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––*/
getsockname(sk,(structsockaddr *)&local, &len);
printf("Socket has port %d\n",local.sin_port);
/*______
The can start accepting requests from clients. It first listens to the socket, declaring willingness to
accept connections. It then accepts requests from clients.
––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––*/
listen(sk,5);
while(1) {
rsk=accept(sk,0,0);/*Accept new request for a connection */
if(fork()==0) {/*Create one child to serve each client*/
dup2(rsk,0);/*Connect the new connection to "stdin"*/
execl("recho","recho",0);
} else
close(rsk);
}
}