Title: Concurrent Servers
1Concurrent Servers
2Idea Behind Concurrent Servers
Server
X
Client 1
Server 1
3Idea Behind Concurrent Servers
Server
Client 1
Server 1
4Idea Behind Concurrent Servers
Server
Client 1
Server 1
Client 2
5Idea Behind Concurrent Servers
Server
Client 1
Server 1
Client 2
Server 2
6Idea Behind Concurrent Servers
Server
Client 1
Server 1
Client 2
Server 2
7Idea Behind Concurrent Servers
Server
X
Client 1
Server 1
Client 2
Server 2
8Idea Behind Concurrent Servers
Server
Client 1
Server 1
Client 2
Server 2
9Creating a New Server - fork()
- listenfd Socket( )
- Initialize server address
- Bind( listenfd, )
- for ( )
- / wait for client connection /
- connfd Accept(listenfd,)
- if( (pid Fork() ) 0)
- /I am the child /
- Close(listenfd)
- service_client(connfd)
- Close(connfd)
- exit(0)
- else / I am the parent /
- Close(connfd)
10Points to Note
- fork() is called once
- but it returns twice!!
- Once in the parent server and
- Once in the child server
- How to distinguish parent and child??
11Points to Note
- fork() is called once
- but it returns twice!!
- Once in the parent server and
- Once in the child server
- How to distinguish parent and child??
- Return value in child 0
- Return value in parent process id of child
12Points to Note
- fork() is called once
- but it returns twice!!
- Once in the parent server and
- Once in the child server
- How to distinguish parent and child??
- Return value in child 0
- Return value in parent process id of child
- Child server exits after servicing the client.
13Running another program in child exec()
14Running another program in child exec()
Inetd daemon
listenfd Socket() Connfd Accept()
15Running another program in child exec()
Inetd child
Inetd daemon
Close(listenfd)
listenfd Socket() Connfd Accept()
Fork()
16Running another program in child exec()
Inetd child
Inetd daemon
Close(listenfd)
listenfd Socket() Connfd Accept()
Fork()
Exec()
Service telnet client Close(connfd)
Telnet server
17Different Types of exec()
- int execl(char pathname, char arg0, , (char
)0) - int execv(char pathname, char argv)
- int execle(char pathname, char arg0, ,
(char )0, char envp) - int execve(char pathname, char argv, char
envp) - int execlp(char filename, char arg0, ,
(char )0) - int execvp(char filename, char argv)
18Properties of exec()
- Replaces current process image with new program
image. - E.g. inetd image replaced by telnet image
- All descriptors open before exec remain open
after exec.
19Getting IP address/port from socket
- int getsockname(int sockfd, struct sockaddr
localaddr, socklen_t addrlen) - Get the local IP/port bound to socket
- int getpeername(int sockfd, struct sockaddr
remoteaddr, socklen_t addrlen) - Get the IP/port of remote endpoint
- Why do we need these?
20Two other useful functions
- struct hostent gethostbyaddr (void addr, size_t
len, int type) - Converts from IP addr to domain name
- struct hostent gethostbyname (char name)
- Converts from domain name to IP address
- struct hostent
- char h_name/ official name of host /
- char h_aliases / alias list /
- int h_addrtype / address type /
- int h_length / address length/
- char h_addr_list / address list /
21Signals
- Signal is a notification to process (from OS or
from another process) that an event has occurred. - Type of event determined by type of signal
- Try listing all signal types using
- kill l
- Some interesting signals
- SIGCHLD, SIGTERM, SIGKILL, SIGSTOP
22Handling Signals
- Signals can be caught i.e. an action associated
with them - SIGKILL and SIGSTOP cannot be caught.
- Actions can be customized using
- sigaction()
- which associates a signal handler with the
signal. - Details in page 120 of Stevens book
- Default action for most signals is to terminate
the process - SIGCHLD and SIGURG are ignored by default.
- Unwanted signals can be ignored
- except SIGKILL or SIGSTOP
23Zombie Processes
- When a child server dies, a SIGCHLD is sent to
the parent server. - If parent doesnt wait()on the child, child
becomes a zombie (status Z seen with ps). - Zombies hang around forever.
24How to avoid zombies?
- Parent should install a signal handler for
SIGCHLD - Call wait()/waitpid()inside the signal handler
- void handle_sigchld(int signo)
- pid_t pid
- int stat
-
- pid wait(stat)
- printf(child d terminated\n, pid)