Concurrent Servers
description
Transcript of Concurrent Servers
![Page 1: Concurrent Servers](https://reader035.fdocuments.net/reader035/viewer/2022062301/56814e35550346895dbb9e79/html5/thumbnails/1.jpg)
Concurrent Servers
![Page 2: Concurrent Servers](https://reader035.fdocuments.net/reader035/viewer/2022062301/56814e35550346895dbb9e79/html5/thumbnails/2.jpg)
Idea Behind Concurrent Servers
Server
Client 1Server 1
X
![Page 3: Concurrent Servers](https://reader035.fdocuments.net/reader035/viewer/2022062301/56814e35550346895dbb9e79/html5/thumbnails/3.jpg)
Idea Behind Concurrent Servers
Server
Client 1Server 1
![Page 4: Concurrent Servers](https://reader035.fdocuments.net/reader035/viewer/2022062301/56814e35550346895dbb9e79/html5/thumbnails/4.jpg)
Idea Behind Concurrent Servers
Server
Client 1Server 1
Client 2
![Page 5: Concurrent Servers](https://reader035.fdocuments.net/reader035/viewer/2022062301/56814e35550346895dbb9e79/html5/thumbnails/5.jpg)
Idea Behind Concurrent Servers
Server
Client 1Server 1
Client 2Server 2
![Page 6: Concurrent Servers](https://reader035.fdocuments.net/reader035/viewer/2022062301/56814e35550346895dbb9e79/html5/thumbnails/6.jpg)
Idea Behind Concurrent Servers
Server
Client 1Server 1
Client 2Server 2
![Page 7: Concurrent Servers](https://reader035.fdocuments.net/reader035/viewer/2022062301/56814e35550346895dbb9e79/html5/thumbnails/7.jpg)
Idea Behind Concurrent Servers
Server
Client 1Server 1
Client 2Server 2
X
![Page 8: Concurrent Servers](https://reader035.fdocuments.net/reader035/viewer/2022062301/56814e35550346895dbb9e79/html5/thumbnails/8.jpg)
Idea Behind Concurrent Servers
Server
Client 1Server 1
Client 2Server 2
![Page 9: Concurrent Servers](https://reader035.fdocuments.net/reader035/viewer/2022062301/56814e35550346895dbb9e79/html5/thumbnails/9.jpg)
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);
}
![Page 10: Concurrent Servers](https://reader035.fdocuments.net/reader035/viewer/2022062301/56814e35550346895dbb9e79/html5/thumbnails/10.jpg)
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??
![Page 11: Concurrent Servers](https://reader035.fdocuments.net/reader035/viewer/2022062301/56814e35550346895dbb9e79/html5/thumbnails/11.jpg)
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
![Page 12: Concurrent Servers](https://reader035.fdocuments.net/reader035/viewer/2022062301/56814e35550346895dbb9e79/html5/thumbnails/12.jpg)
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.
![Page 13: Concurrent Servers](https://reader035.fdocuments.net/reader035/viewer/2022062301/56814e35550346895dbb9e79/html5/thumbnails/13.jpg)
Running another program in child – exec()
![Page 14: Concurrent Servers](https://reader035.fdocuments.net/reader035/viewer/2022062301/56814e35550346895dbb9e79/html5/thumbnails/14.jpg)
Running another program in child – exec()
listenfd = Socket(…)Connfd = Accept(…)
Inetd daemon
![Page 15: Concurrent Servers](https://reader035.fdocuments.net/reader035/viewer/2022062301/56814e35550346895dbb9e79/html5/thumbnails/15.jpg)
Running another program in child – exec()
listenfd = Socket(…)Connfd = Accept(…)
Inetd daemon
Close(listenfd)Fork(…)
Inetd child
![Page 16: Concurrent Servers](https://reader035.fdocuments.net/reader035/viewer/2022062301/56814e35550346895dbb9e79/html5/thumbnails/16.jpg)
Running another program in child – exec()
listenfd = Socket(…)Connfd = Accept(…)
Inetd daemon
Close(listenfd)Fork(…)
Exec(…)
Service telnet clientClose(connfd)
Inetd child
Telnet server
![Page 17: Concurrent Servers](https://reader035.fdocuments.net/reader035/viewer/2022062301/56814e35550346895dbb9e79/html5/thumbnails/17.jpg)
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[]);
![Page 18: Concurrent Servers](https://reader035.fdocuments.net/reader035/viewer/2022062301/56814e35550346895dbb9e79/html5/thumbnails/18.jpg)
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.
![Page 19: Concurrent Servers](https://reader035.fdocuments.net/reader035/viewer/2022062301/56814e35550346895dbb9e79/html5/thumbnails/19.jpg)
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?
![Page 20: Concurrent Servers](https://reader035.fdocuments.net/reader035/viewer/2022062301/56814e35550346895dbb9e79/html5/thumbnails/20.jpg)
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 */
}
![Page 21: Concurrent Servers](https://reader035.fdocuments.net/reader035/viewer/2022062301/56814e35550346895dbb9e79/html5/thumbnails/21.jpg)
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
![Page 22: Concurrent Servers](https://reader035.fdocuments.net/reader035/viewer/2022062301/56814e35550346895dbb9e79/html5/thumbnails/22.jpg)
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
![Page 23: Concurrent Servers](https://reader035.fdocuments.net/reader035/viewer/2022062301/56814e35550346895dbb9e79/html5/thumbnails/23.jpg)
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.
![Page 24: Concurrent Servers](https://reader035.fdocuments.net/reader035/viewer/2022062301/56814e35550346895dbb9e79/html5/thumbnails/24.jpg)
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);
}