Chapter05 TCP Client Server Example
Chapter05 TCP Client Server Example
Concept
5.1 Introduction 5.2 TCP Echo Server: main Function 5.3 TCP Echo Server: str_echo Function 5.4 TCP Echo Client: main Function 5.5 TCP Echo Client: str_cli Function 5.6 Normal Startup 5.7 Normal Termination 5.8 POSIX Signal Handling 5.9 Handling SIGCHLD Signals 5.10 wait and waitpid Functions 5.11 Connection Abort before accept Returns 5.12 Termination of Server Process 5.13 SIGPIPE Signal 5.14 Crashing of Server Host 5.15 Crashing and Rebooting of Server Host 5.16 Shutdown of Server Host 5.17 Summary of TCP Example 5.18 Data Format 5.19 Summary
2
5.1 Introduction
Echo Client & Server
stdin stdout fgets fputs TCP client writen readline readline writen TCP client
The client reads a line of text from its standard input and writes the line to the server. The server reads the line from its network input and echoes the line back to the client. The client reads the echoed line and prints it on its standard output
5.1 Introduction
Implementation of an echo server
A client/server that echoes input lines is a valid, yet simple, example of a network application.
Besides running out client and server in their normal mode, we examine lots of boundary conditions for this example:
what happens:
when the client and server are started. when the client terminates normally. to the client if the server process terminates before the client is done. to the client if the server host crashes. and so on
4
Server Accept
SY N
Client
Connect wait_for_connect
wait_for_connect
ACK, SYN
A CK
read tcp_data_wait
D A TA
ACK
write ESTABLISHED
ESTABLISHED
10
11
12
13
3.
4.
5. 6.
7.
EOF (control+D) , fgets null , str_cli . main str_cli exit . , descriptor close, close. FIN , ACK . , CLOSE_WAIT , FIN_WAIT_1 . FIN , readline 0 , str_cli Child main exit . , descriptor close, TCP TIME_WAIT . , SIGCHLD .
SIGCHLD .
14
15
16
17
18
We can ignore a signal by setting its disposition to SIG_IGN. The two signals SIGKILL and SIGSTOP cannot be ignored. We can set the default disposition for a signal by setting its disposition to SIG_DFL. The default is normally to terminate a process on receipt of a signal, with certain signals also generating a core image of the process in its current working directory.
19
21
If a process terminates, and that process has children in the zombie state, the parent process ID of all the zombie children is set to 1(the init process), which will inherit the children and clean them up(i.e., init will wait for them, which removes the zombie).
22
23
24
25
26
waitpid Function
waitpid gives us more control over which process to wait for and whether or not to block.
First, the pid argument lets us specify the process ID that we want to wait to wait for.
A value of -1 says to wait for the first of our children to terminate.
27
28
29
void sig_chld(int signo) { pid_t pid; int stat; while ( (pid = waitpid(-1, &stat, WNOHANG)) > 0) printf("child %d terminated\n", pid); return; }
30
2.
3.
We must catch the SIGCHLD signal when forking child processes. We must handle interrupted system calls when we catch signals. A SIGCHLD handler must be coded correctly using waitpid to prevent any zombies from being left around.
31
32
.
Berkeley-derived implementations: , . SVR4 implementations: EPROTO(protocol error) errno . POSIX: ECONNABORTED .
33
34
Server (tcpserv04.c)
Client (tcpcli04.c)
35
36
37
38
Client (tcpcli04.c)
Server (tcpserv04.c)
39
40
42
The problem in this example is that the client is blocked in the call to fgets when the FIN arrives on the socket. The client is really working with two descriptors-the socket and the user input-and instead of blocking on input from only one of the two sources, it should block on input from either source.
43
45
47
2.
3.
4.
When the server host crashes, nothing is sent out on the existing network connections. We type a line of input to the client, it is writen by writen, and is sent by the client TCP as a data segment. The client then blocks in the call to readline, waiting for the echoed reply. We will see the client TCP continually retransmitting the data segment, trying to receive an ACK from the server. When the client TCP fanally gives up, an error is returned to the client process.
48
4.
5.
Start the server and then the client. The server host crashes and reboots. Type a line of input to the client, which is sent as a TCP data segment to the server host. When the server host reboots after crashing, its TCP loses all information about connections that existed before the crash. Therefore, the server TCP responds to the received data segment from the client with an RST. Client is blocked in the call to readline when the RST is received, causing readline to return the error ECONNRESET.
49
51
52
53
54