Presentation is loading. Please wait.

Presentation is loading. Please wait.

Chapter 5. TCP Client-Server Example

Similar presentations


Presentation on theme: "Chapter 5. TCP Client-Server Example"— Presentation transcript:

1 Chapter 5. TCP Client-Server Example

2 Contents Introduction TCP Echo Server TCP Echo Client
Normal Startup and Termination Posix Signal Handling Handling SIGCHLD Signals Data Format and so on...

3 5.1 Introductioon TCP client server stdin stdout fgets fputs writen readline 1. The Client reads a line of text from its standard input and writes the line to the server. 2. The server reads the line from its network input and echoes the line back to the client. 3. The client reads the echoed line and prints it on its standard output.

4 5.2 TCP Echo Server main function & str_echo function for ( ; ; ) {
clilen = sizeof(cliaddr); connfd = Accept(listenfd, (SA *) &cliaddr, &clilen); if ( (childpid = Fork()) == 0) {/* child process */ Close(listenfd);/* close listening socket */ str_echo(connfd);/* process the request */ exit(0); } Close(connfd); /* parent closes connected socket */

5

6 void str_echo(int sockfd)
{ ssize_t n; char line[MAXLINE]; for ( ; ; ) { if ( (n = Readline(sockfd, line, MAXLINE)) == 0) return; /* connection closed by other end */ Writen(sockfd, line, n); }

7 5.4 TCP Echo Client main function & str_cli function
Connect(sockfd, (SA *) &servaddr, sizeof(servaddr)); str_cli(stdin, sockfd); /* do it all */ exit(0);

8

9 void str_cli(FILE *fp, int sockfd)
{ char sendline[MAXLINE], recvline[MAXLINE]; while (Fgets(sendline, MAXLINE, fp) != NULL) { Writen(sockfd, sendline, strlen(sendline)); if (Readline(sockfd, recvline, MAXLINE) == 0) err_quit("str_cli: server terminated prematurely"); Fputs(recvline, stdout); }

10 Normal Startup How the client and server start, how they end
What happens when something goes wrong the client host crashes, the client process crashes, network connectivity is lost Test method tcpserv & netstat -a tcpcli (local test) ps -l

11 Normal Termination tcpcli 127.0.0.1 netstat -a | grep procID ps
hello, world good bye ^D netstat -a | grep procID ps 19130 p1 Ss -ksh 21130 p1 I ./tcpserv 21132 p1 Z (tcpserv) (Z:zombie process)

12 5.8 Posix Signal Handling A signal (software interrupt) : a notification to a process that an event has occurred. Signals can be sent by one process to another process(or itself) by the kernel to a process SIGCHLD signal: a signal sent by the kernel whenever a process terminates, to the parent of the terminating process

13 Every signal has a disposition (action associated with the signal)
We can provide a function hat is called whenever a specific signal occurs. This function is called a signal handler and this action is called catching the signal. (SIGKILL(x) and SIGSTOP(X)), void handler(int signo); We can ignore a signal by setting its disposition to SIG_IGN. (SIGKILL(x) and SIGSTOP(X)), We can set the default disposition for a signal by setting its disposition to SIG_DFL. (terminate a process on the receipt of a signal) SIGCHLD(X), SIGURG(x)

14 5.8 Posix Signal Handling signal Function
Sigfunc * signal(int signo, Sigfunc *func) { struct sigaction act, oact; act.sa_handler = func; sigemptyset(&act.sa_mask); act.sa_flags = 0; if (signo == SIGALRM) { #ifdef SA_INTERRUPT act.sa_flags |= SA_INTERRUPT; /* SunOS 4.x */ #endif } else { #ifdef SA_RESTART act.sa_flags |= SA_RESTART; /* SVR4, 44BSD */ } if (sigaction(signo, &act, &oact) < 0) return(SIG_ERR); return(oact.sa_handler);

15 5.8 Posix Signal Handling 2-3
normal function prototype void (*signal(int signo, void (*func) (int) ) ) (int); define Sigfunc type in unp.h header typedef void Sigfunc(int); The function prototype Sigfunc *signal(int signo, Sigfunc *func); 6 : The sa_handler member of the sigaction structure is set to the func argument. members of sigaction structure void (*) (int) sa_handler sigset_t sa_mask int sa_flag

16 5.8 Posix Signal Handling 7 : Set signal mask for handler
Posix allow us to specify a set of signals that will be blocked when our signal handler is called. Any signal that is blocked cannot be delivered to the process. #include <signal.h> int sigaddset(sigset_t *set, int signo); int sigemptyset(sigset_t *set); int sigfillset(sigset_t *set); int sigdelset(sigset_t *set, int signo); int sigismember(sigset_t *set, int signo); int sigprocmask(int how, const sigset_t *set, sigset_t *oset); SIG_BLOCK SIG_SETMASK SIG_UNBLOCK

17 5.8 Posix Signal Handling SIGALRM SA_RESTART
place a timeout on an I/O operation SA_RESTART a system call interrupted by this signal will be automatically restarted by the kernel

18 5.8 Posix Signal Handling Posix Signal Semantics
Once a signal handler is installed, it remains installed. While a signal handler is executing, the signal being delivered is blocked. If a signal is generated one or more times while it is blocked, it is normally delivered only one time after the signal is unblocked. That is, by default Unix signals are not queued. It is possible to selectively block and unblock a set of signals using the sigprocmask function.

19 Handling SIGCHLD Signals
Zombie State maintain information about the child for the parent to fetch at some later time the process ID of the child, its termination status, the resource of the child(CPU time, memory) the parent process ID of all the zombie children: 1(init process)-inherit the children and clean them up <defunct> Handling Zombies space waste of the kernel, out of process wait for the children to prevent them from becoming zombies

20 Handling SIGCHLD Signals
We establish the signal handler by adding the function call Signal (SIGCHLD, sig_chld); in Figure 5.2, after the call to listen. #include "unp.h" void sig_chld(int signo) { pid_t pid; int stat; pid = wait(&stat); printf("child %d terminated\n", pid); return; } Figure 5.7 Version of SIGCHLD signal handler that calls wait

21 Tcpserv02 & tcpcli01 127.0.0.1 hi, there ^D child 16942 terminated
accept error: Interrupted system call // the parent is blocked in its call to accept when the SIGCHLD is delivered //sig_chld function executes, wait fetches the child’PID and termination status, printf // kernel causes the accept to return an error of EINTER

22 5.9 Handling SIGCHLD Signals
Handling Interrupted System Calls for ( ; ; ) { clilen = sizeof(cliaddr); if( (connfd=accept(listenfd,(SA *) &cliaddr,&clilen)) < 0) { if( errno == EINTER ) continue; else err_sys(“accept error”); }

23 5.10 wait and waitpid Functions
pit_t: the process ID of the terminated child statloc : the termination status of the child(an integer) is returned through the statloc pointer. pid : specify the process ID that we want to wait for. A value of -1 say to wait for the first of our children to terminate. option : specify additional option. The most common option is WNOHANG. #include <sys/wait.h> pid_t wait(int *statloc); pid_t waitpid(pid_t pid, int *statloc, int option);

24

25 >tcpserv03 & >tcpcli hello ^D child terminated p1 S ./tcpserv03 p1 Z (tcpcli03) p1 Z (tcpcli03) p1 Z (tcpcli03) p1 Z (tcpcli03)

26 5.10 wait and waitpid Functions
Difference between wait and waitpid the problem is that all five signals are generated before the signal handler is executed, and the signal handler is executed only one time because Unix signals are normally not queued. waitpid we must specify the WNOHANG option: this tells waitpid not to block if there exist running children that have not yet terminated. void sig_chld(int signo) { pid_t pid; int stat; while((pid = waitpid(-1,&stat,WNOHANG)) > 0) printf("child %d terminated\n", pid); return; }

27

28 5.11 Connection Abort before accept Returns
The three-way handshake completes, the connection is established, and then the client TCP sends an RST(reset). On the server side the connection is queued by its TCP, waiting for the server process to call accept when the RST arrives. Some time later the server process calls accept.

29 Implementation BSD : kernel SVR4 : return an errno of EPROTO Posix.1g : return an errno of ECONNABORTED EPROTO : returned when some fatal protocol-related events occur on the streams subsystem. In the case of the ECONNABORTED error, the server can ignore the error and just call accept again.

30 5.12 Termination of Server Process
Our client is not expecting to receive an end-of-file at this point so it quits with the error message “server terminated prematurely”. solaris % tcpcli hello another line str_cli: server terminated prematurely

31 SIGPIPE Signal What happens if the client the error return from readline and writes more data to the server ? When a process writes to a socket that has received an RST, the SIGPIPE signal is sent to the process Default action of SIGPIPE: terminate the process

32 >tcpcli hi there bye Nothing is echoed for bye data Reason: the default action of SIGPIPE is terminate the process.

33 What happens when the server host crashes, reboots, shutdowns


Download ppt "Chapter 5. TCP Client-Server Example"

Similar presentations


Ads by Google