Presentation is loading. Please wait.

Presentation is loading. Please wait.

Chapter 5 (part 1) TCP Client /Server Example By: Lim Meng Hui.

Similar presentations


Presentation on theme: "Chapter 5 (part 1) TCP Client /Server Example By: Lim Meng Hui."— Presentation transcript:

1 Chapter 5 (part 1) TCP Client /Server Example By: Lim Meng Hui

2 Outline Introduction TCP Echo Server TCP Echo Client Normal Startup
Normal Termination POSIX Signal Handling Handling SIGCHLD Signals

3 Simple Echo Client / Server
fgets writen read TCP Client TCP Server stdin stdout fputs readline writen 1. Client: - Reads a line of text - Writes the line to the server 2. Server: - Reads the line from its network input - Echoes the line back to the client 3. Client: - Reads the echoed line - Prints the line on its standard output

4 TCP Echo Server: main Function
1 #include "unp.h" 2 int 3 main(int argc, char ** argv) 4 { 5 int listenfd, connfd; 6 pid_t childpid; 7 socklen_t clilen; 8 struct sockaddr_in cliaddr, servaddr; 9 listenfd = Socket (AF_INET, SOCK_STREAM, 0); bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl (INADDR_ANY); servaddr.sin_port = htons (SERV_PORT); //9877 14 Bind(listenfd, (SA *) &servaddr, sizeof(servaddr)); // Assign local protocol address to a socket Listen(listenfd, LISTENQ); 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 */ } fork spawns child child handles new client child closes listening socket parent closes connected socket

5 TCP Echo Server: str_echo Function
1 #include "unp.h“ 2 void 3 str_echo (int argc, char ** argv) 4 { ssize_t n; char buf[MAXLINE]; 7 again: 8 while ((n = read(sockfd, buf, MAXLINE)) > 0) Writen (sockfd, buf, n); If (n < 0 && errno == EINTR) goto again; else if (n < 0) err_sys (“str_echo: read error”); 14 } Function: Reads data from the client & echoes it back to the client. If client FIN is received, a) child’s read return 0. b) str_echo function returns. c) child is terminated.

6 TCP Echo Client: main Function
1 #include "unp.h" 2 int 3 main(int argc, char **argv) 4 { 5 int sockfd; struct sockaddr_in servaddr; 7 if (argc != 2) err_quit("usage: tcpcli <IPaddress>"); sockfd = Socket(AF_INET, SOCK_STREAM, 0); 10 bzero(&servaddr, sizeof(servaddr)); 11 servaddr.sin_family = AF_INET; 12 servaddr.sin_port = htons(SERV_PORT); Inet_pton(AF_INET, argv[1], &servaddr.sin_addr); Connect(sockfd, (SA *) &servaddr, sizeof(servaddr)); 15 str_cli(stdin, sockfd); /* do it all */ 16 exit(0); 17 }

7 TCP Echo Client: str_cli Function
1 #include "unp.h" 2 void 3 str_cli (FILE *fp, int sockfd) 4 { char sendline[MAXLINE], recvline[MAXLINE]; while (Fgets(sendline, MAXLINE, fp) != NULL) { 7 Writen (sockfd, sendline, strlen (sendline); if (Readline(sockfd, sendline, strlen (sendline)) err_quit (“str_cli: server terminated prematurely”); 10 Fputs (recvline, stdout); 11 } 12} fgets: read a line of text. writen: sends the line to the server. readline: reads the line echoed back from the server. fputs: writes it to standard output. When EOF/error is encountered, a) fgets returns a null pointer b) loop terminates

8 Normal Startup (1) Client calls socket and connect.
Start the server in the background of linux host. When server starts, it calls socket, bind, listen, and accept, blocking in the call to accept. Run the netstat program to verify the state of the server’s listening socket. Client calls socket and connect. When three-way handshake completes, connect returns in the client and accept returns in the server.

9 Normal Startup (2) After connection is established,
a) Client calls str_cli, block in the call to fgets (wait for input). 1 #include "unp.h" 2 void 3 str_cli (FILE *fp, int sockfd) 4 { char sendline[MAXLINE], recvline[MAXLINE]; while (Fgets(sendline, MAXLINE, fp) != NULL) { 7 Writen (sockfd, sendline, strlen (sendline); if (Readline(sockfd, sendline, strlen (sendline)) err_quit (“str_cli: server terminated prematurely”); 10 Fputs (recvline, stdout); 11 }

10 Normal Startup (3) After connection is established,
b) When accept returns in the server, it calls fork and the child calls str_echo. This function read, which blocks while waiting for a line to be sent from the client. 1 #include "unp.h“ 2 void 3 str_echo (int argc, char ** argv) 4 { ssize_t n; char buf[MAXLINE]; 7 again: 8 while ((n = read(sockfd, buf, MAXLINE)) > 0) Writen (sockfd, buf, n); If (n < 0 && errno == EINTR) goto again; else if (n < 0) err_sys (“str_echo: read error”); 14 }

11 Normal Startup (4) After connection is established,
1 #include "unp.h" 2 int 3 main(int argc, char ** argv) 4 { 5 int listenfd, connfd; 6 pid_t childpid; : 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 */ } After connection is established, c) Again, the server parent calls accept again, and blocks while waiting for the next client connection.

12 Normal Startup (5) When the three-way handshake completes,
connect returns when the second segment of the handshake is received by the client accept does not return until the third segment of the handshake is received by the server.

13 Normal Termination (1)

14 Normal Termination (2) Normal termination of client and server:
Type in EOF character, fgets returns null pointer and the function str_cli returns. When str_cli returns to the client main function, the latter terminates by calling exit. - Kernel closes client socket. - This sends a FIN to the server. - The server TCP responds with an ACK. d) - TCP receives the FIN. - The server child is blocked in a call to readline and readline then returns 0. - str_echo function return to the server child main.

15 Normal Termination (3) e) The server child terminates by calling exit.
f) - All open descriptors in the server child are closed. - The closing of the connected socket by the child causes : i) a FIN from the server to the client ii) an ACK from the client g) Finally, the SIGCHLD signal is sent to the parent when the server child terminates. If ignored, the child enters the zombie state and remains forever. Zombie state: When a child process exits, it is not immediately cleared off the process table. Instead, a signal is sent to its parent process, which needs to acknowledge it's child's death, and only then the child process is completely removed from the system. In the duration before the parent's acknowledgment and after the child's exit, the child process is in a state called "zombie".

16 POSIX Signal Handling (1)
Signal : a notification to a process that an event has occurred. : known as software interrupts. : usually occur asynchronously. Signals can be sent by: one process to another the kernel to a process Disposition : the action associated with the signal : set by sigaction function 3 choices for the disposition: - provide a function (signal handler) that is called whenever a specific signal occurs. Function Prototype: void handler (int signo); - ignore a signal by setting its disposition to SIG_IGN. - set the default disposition for a signal by setting its disposition to SIG_DFL

17 POSIX Signal Handling (2)
The POSIX way to establish the disposition of a signal is to call the sigaction function. An easier way to set the disposition of a signal is to call the signal function.

18 POSIX Signal Handling (3)
Set handler: - The sa_handler member of the sigaction structure is set to the func argument. Set signal mask for handler: When our signal handler is called, a set of signals will be blocked (cannot be delivered to a process). the sa_mask member is set to the empty set so that no additional signals will be blocked while our signal handler is running. Set SA_RESTART flag: - Optional flag - When SA_RESTART flag is set, a system call interrupted by this signal will be automatically restarted by the kernel.

19 POSIX Signal Handling (4)
POSIX Signal Semantics: Signal handling on a POSIX-compliant system: Once a signal handler is installed, it remains installed. While a signal handler is executing, the signal being delivered is blocked. Furthermore, any additional signals that were specified in the sa_mask signal set passed to sigaction when the handler was installed are also 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. It is possible to selectively block and unblock a set of signals using the sigprocmask function in order to protect a critical region of code by preventing certain signals from being caught while that region of code is executing.

20 Handling sigchld signals (1)
The purpose of the zombie state: - to maintain information about the child 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.). 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.

21 Handling sigchld signals (2)

22 Handling sigchld signals (3)
The sequence of steps is as follows: We terminate the client by typing our EOF character. The client TCP sends a FIN to the server and the server responds with an ACK. The receipt of the FIN delivers an EOF to the child's pending readline. The child terminates. The parent is blocked in its call to accept when the SIGCHLD signal is delivered. The sig_chld function executes (our signal handler), wait fetches the child's PID and termination status, and printf is called from the signal handler. The signal handler returns. Since the signal was caught by the parent while the parent was blocked in a slow system call (accept), the kernel causes the accept to return an error of EINTR (interrupted system call). The parent does not handle this error so it aborts.

23 To be continued… Thank You!


Download ppt "Chapter 5 (part 1) TCP Client /Server Example By: Lim Meng Hui."

Similar presentations


Ads by Google