Concurrent Servers
description
Transcript of Concurrent Servers
Concurrent Servers
Idea Behind Concurrent Servers
Server
Client 1Server 1
X
Idea Behind Concurrent Servers
Server
Client 1Server 1
Idea Behind Concurrent Servers
Server
Client 1Server 1
Client 2
Idea Behind Concurrent Servers
Server
Client 1Server 1
Client 2Server 2
Idea Behind Concurrent Servers
Server
Client 1Server 1
Client 2Server 2
Idea Behind Concurrent Servers
Server
Client 1Server 1
Client 2Server 2
X
Idea Behind Concurrent Servers
Server
Client 1Server 1
Client 2Server 2
Creating a New Server - fork()listenfd = Socket( … )Initialize server addressBind( 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);
}
Points 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??
Points 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
Points 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.
Running another program in child – exec()
Running another program in child – exec()
listenfd = Socket(…)Connfd = Accept(…)
Inetd daemon
Running another program in child – exec()
listenfd = Socket(…)Connfd = Accept(…)
Inetd daemon
Close(listenfd)Fork(…)
Inetd child
Running another program in child – exec()
listenfd = Socket(…)Connfd = Accept(…)
Inetd daemon
Close(listenfd)Fork(…)
Exec(…)
Service telnet clientClose(connfd)
Inetd child
Telnet server
Different 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[]);
Properties 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.
Getting 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?
Two 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 */
}
Signals
• 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
Handling 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 Steven’s 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
Zombie Processes
• When a child server dies, a SIGCHLD is sent to the parent server.
• If parent doesn’t wait()on the child, child becomes a zombie (status “Z” seen with ps).
• Zombies hang around forever.
How 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);
}