Concurrent Servers/Iterative server:
A server that handles a simple program such as
daytime server is a iterative server. But when the client request can take
longer to service, the server should not be tied upto a single client.
The server must be capable of handling multiple
clients at the same time. The simplest way to write a concurrent server under
Unix is to fork a child process to handle each client. Following program shows
the typical concurrent server.
pid_t
pid;
int
listenfd, connfd;
listfd = socket ( , , , ); /*fill in sockaddr_in with server’s well
known port*/ bind (listenfd, …);
listen (listenfd, LISTENQ);
for ( ; ; ) {
connfd = accept (listenfd, …); if ( (pid =
fork())== 0) {
close (listenfd); /* child closed listening socket */ doit (connfd);
/* process the request */
close ( connfd); /* done with the client*/ exit (0); /* child
terminates*/
}
close (connfd); /* parent closes connected socket*/
}
When a connection is established , accept returns, the server calls fork, and then the child process services the client ( on connfd, the connected socket ) and the parent process waits for another connection ( on listenfd, the listening socket ). The parent closes the connected socket since the child handles this new client.
In the above program, the function doit does whatever is required to
service the client. When this functions returns, we explicitly close the connected socket in the
child. This is not required since the next statement calls exit, and part of process termination is closing all open
descriptors by the kernal. Whether to include this explicit call to close or not is a matter of personal
programming taste.
The connection scene in case of concurrent
server is shown below:
close() The normal Unix close() is also used to close a socket and terminate a TCP connection.
#include<unistd.h>
int close (int sockfd);
The
default action of close with a TCP socket is to mark the socket as closed and
return to the process immediately. The socket descriptor is no longer usable by
the process. Thst is , it can not be used as an argument to read or write.
getsockname () and getpeername():
These
two functions return either the local protocol address associated with a socket
or the foreign address associated with a socket.
#include <sys/socket.h>
int getsockname(int sockfd, struct sockaddr
*localadddr, socklen_t *addlen);
int getpeername(int sockfd, struct sockaddr
*peeradddr, socklen_t *addlen); both return 0 if OK and –1 on
error.
These functions are required for the following
reasons.
a. After connect successfully returns a TCP client
that does not call bind(),
getsocketname() returns the local IP address and local port number assigned
to the connection by the kernel
b. After calling bind with a port number of 0, getsockname() returns the local port
number that was assigned
c. When the server is exceed by the process that calls accept(), the only way the server can obtain the identity of the
client is to call getpeername().
Related Topics
Privacy Policy, Terms and Conditions, DMCA Policy and Compliant
Copyright © 2018-2024 BrainKart.com; All Rights Reserved. Developed by Therithal info, Chennai.