Chapter 5
Chapter 5
Server
School of Information and Communication Technology,
Hanoi University of Science and Technology
References
[1] W.Richard Stevens, Unix Network Programming Vol.1, 3rd Ed., Prentice
Hall.
[2] Keir Davis, John W. Turner, and Nathan Yocom, The Definitive Guide to
Linux Network Programming, Apress.
[3] Michael Donahoo, Kenneth Calvert, TCP/IP Sockets in C: Practical Guide
for Programmers, Elsevier.
2
Content
• Forking Server
• Signaling
• Signal Handling
3
Single-client Server
4
Fork process
• fork is an operation where a process creates a
copy of itself
• Happen in multitask operating system when a
process launch another process child process
• The parent process makes a copy of its memory
and gives to the child process
• Fork system call is first introduced in UNIX.
• First process in Linux is “init”
#include <unistd.h>
pid_t fork(void);
5
fork examples
6
fork examples
7
fork
pid_t pid;
int listenfd, connfd;
listenfd = socket( ... );
/* fill in sockaddr_in{} with server's well-known port */
bind(listenfd, ... );
listen(listenfd, 5);
for ( ; ; ) {
connfd = accept (listenfd, ... ); /* probably blocks */
if((pid = fork()) == 0) {
close(listenfd); /* child closes listening socket */
doit(connfd); /* process the request */
close(connfd); /* done with this client */
exit(0); /* child terminates */
}
close(connfd); /* parent closes connected socket */
}
8
Child Process Termination
• We use forking server, when a child process ends, it
sends the SIGCHLD signal to the parent
• Information about the child process is still maintained in “process
table” in order to allow its parent to read the child exit status
afterward.
• If SIGCHLD is ignored
• Child process will not running but still consumes system
resources (in process table)
• it is in zombie state
• We need to handle SIGCHLD signal
• Make the child process to wait until the parent read its exit status
• once the exit status is read via “wait” system call, the zombie's
entry is removed from the process table
•
9
Signaling
• A signal is a notification to a process that an
event has occurred.
• Signals are sometimes called software
interrupts.
• Signals usually occur asynchronously.
• A process doesn't know ahead when a signal will
occur.
• Signals can be sent
• By one process to another process (or to itself)
• By the kernel to a process
10
Signaling
• Typing certain key combinations at the controlling
terminal of a running process causes the system to
send it certain signals:
• Ctrl-C sends an INT signal ("interrupt", SIGINT)
• Ctrl-Z sends a TSTP signal ("terminal stop", SIGTSTP)
• Ctrl-\ sends a QUIT signal (SIGQUIT)
• by default, this causes the process to terminate and dump core.
• SIGHUP is sent to a process when its controlling
terminal is closed (a hangup).
• SIGTERM is sent to a process to request its
termination.
• Unlike the SIGKILL signal, it can be caught and
interpreted or ignored by the process.
11
PARENT
C1 C2 C3
13
Handle a signal using sigaction
• Three choices for the disposition:
• We can provide in sigaction a function that is called
whenever a specific signal occurs (sa_handler)
Prototype: void handler (int signo);
• We can ignore a signal by setting sa_handler to
SIG_IGN
• We can set the default disposition for a signal by
setting sa_handler to SIG_DFL.
14
Example
15
Handle a signal using signal function
• An alternative to use sigaction.
• <signal.h>
• void (*signal(int sig, void (*func)(int)))(int)
• Sig: signal to be handled
• func: a pointer to a function that handle the signal
• Meaning: registration of a function for handling a signal.
16
Example
17
Handling SIGCHLD Signals
• The purpose of the zombie state is to maintain information
about the child in “process table” for the parent to fetch at
some later time.
• This information includes the process ID of the child, its
termination status, and information on the resource utilization
of the child (CPU time, memory, etc.).
• They take up space in the kernel and eventually we can run
out of processes
Whenever we fork children, parent must wait (read exit status)
for them to prevent them from becoming zombies
establish a signal handler to catch SIGCHLD, and within the handler, we
call wait
Add into server: signal (SIGCHLD, handler);
18
wait() and waitpid()
#include <sys/wait.h>
19
wait()
• wait for state changes in a child of the calling
process
• In the case of a terminated child, performing a wait
allows the system to release the resources
associated with the child;
• if a wait is not performed, then the terminated child
remains in a "zombie" state
20
wait() vs waitpid()
21
wait() vs waitpid()
22
waitpid()
pid_t waitpid (pid_t pid, int *statloc, int options);
• pid < 0: wait for status change of any child process whose
process group ID is equal to the absolute value of pid.
• pid = -1: wait for for status change of any child process.
• pid = 0: wait for any child process whose process group ID is
equal to that of the calling process
• pid > 0: wait for the child whose process ID is equal to the value of
pid
• Without option WNOHANG, waitpid blocks until the status
change
• With option WNOHANG, waitpid returns immediately
• Return
• Pid of the child whose state has changed
• With option WNOHANG, return 0 if the specified process has not
changed status.
23
Forking server
pid_t pid;
int listenfd, connfd;
signal(SIGCHLD,sig_chld);
listenfd = socket( ... );
bind(listenfd, ... );
listen(listenfd, 5);
for ( ; ; ) {
connfd = accept (listenfd, ... ); /* probably blocks */
if( (pid = fork()) == 0) {
close(listenfd); /* child closes listening socket */
doit(connfd); /* process the request */
close(connfd); /* done with this client */
exit(0); /* child terminates */
}else
close(connfd); /* parent closes connected socket */
}
24
sig_chld: SIGCHLD handler
26
File Sharing
• Viết một chương trình server và 1 client
• Server:
• Fork để tạo 1 tiến trình con chuyên recvfrom (6000) từ các
client broadcast <TÊN> và lưu thông tin <IP> <TÊN> vào 1 file
dùng chung.
• Fork để tạo 1 tiến trình con chuyên đợi TCP 5000 và accept:
Mỗi lần accept tạo một kết nối và trả về danh sách các <IP> và
<TÊN> cho client rồi đóng luôn kết nối.
• Client:
• Fork để tạo 1 tiến trình con chuyên broadcast tên (nhập từ bàn
phím) đến cổng 6000 (toàn mạng)
• Fork để tạo 1 tiến trình con chuyên hỏi danh sách từ
server:5000
27
Q&A
28