54
1 1 Unix Network Unix Network Programming Programming 5. TCP Client/Server Example 5. TCP Client/Server Example 컴퓨터과학과 컴퓨터과학과 이정호 이정호

Chapter05 TCP Client Server Example

Embed Size (px)

Citation preview

Page 1: Chapter05 TCP Client Server Example

11

Unix Network Unix Network ProgrammingProgramming

5. TCP Client/Server Example5. TCP Client/Server Example컴퓨터과학과컴퓨터과학과

이정호이정호

Page 2: Chapter05 TCP Client Server Example

22

ConceptConcept5.1 Introduction5.1 Introduction5.2 TCP Echo Server: 5.2 TCP Echo Server: mainmain FunctionFunction5.3 TCP Echo Server: 5.3 TCP Echo Server: str_echostr_echo FunctionFunction5.4 TCP Echo Client: 5.4 TCP Echo Client: mainmain FunctionFunction5.5 TCP Echo Client: 5.5 TCP Echo Client: str_clistr_cli FunctionFunction5.6 Normal Startup5.6 Normal Startup5.7 Normal Termination5.7 Normal Termination5.8 POSIX Signal Handling5.8 POSIX Signal Handling5.9 Handling 5.9 Handling SIGCHLDSIGCHLD SignalsSignals5.10 5.10 waitwait and and waitpidwaitpid FunctionsFunctions5.11 Connection Abort before 5.11 Connection Abort before acceptaccept ReturnsReturns5.12 Termination of Server Process5.12 Termination of Server Process5.13 5.13 SIGPIPESIGPIPE SignalSignal5.14 Crashing of Server Host5.14 Crashing of Server Host5.15 Crashing and Rebooting of Server Host5.15 Crashing and Rebooting of Server Host5.16 Shutdown of Server Host5.16 Shutdown of Server Host5.17 Summary of TCP Example5.17 Summary of TCP Example5.18 Data Format5.18 Data Format5.19 Summary5.19 Summary

Page 3: Chapter05 TCP Client Server Example

33

5.1 Introduction5.1 Introduction

Echo Client & ServerEcho Client & Server

The client reads a line of text from its standard input and writThe client reads a line of text from its standard input and writes the line es the line to the server.to the server.The server reads the line from its network input and echoes the The server reads the line from its network input and echoes the line line back to the client.back to the client.The client reads the echoed line and prints it on its standard oThe client reads the echoed line and prints it on its standard output

TCPclient

TCPclient

writen

readline

readline

writen

fgets

fputs

stdin

stdout

Figure 5.1 Simple echo client and server

utput

Page 4: Chapter05 TCP Client Server Example

44

5.1 Introduction5.1 IntroductionImplementation of an echo serverImplementation of an echo server

A client/server that echoes input lines is a valid, yet simple, A client/server that echoes input lines is a valid, yet simple, example of a network application.example of a network application.

Besides running out client and server in their normal Besides running out client and server in their normal mode, we examine lots of boundary conditions for mode, we examine lots of boundary conditions for this example:this example:

what happens:what happens:•• when the client and server are started.when the client and server are started.•• when the client terminates normally.when the client terminates normally.•• to the client if the server process terminates before the clientto the client if the server process terminates before the client is is

done.done.•• to the client if the server host crashes.to the client if the server host crashes.•• and so onand so on……

Page 5: Chapter05 TCP Client Server Example

55

5.2 TCP Echo Server: 5.2 TCP Echo Server: mainmain FunctionFunction#include "#include "unp.hunp.h""

intintmain(intmain(int argcargc, char **, char **argvargv)){{

intint listenfdlistenfd, , connfdconnfd;;pid_tpid_t childpidchildpid;;socklen_tsocklen_t clilenclilen;;structstruct sockaddr_insockaddr_in cliaddrcliaddr, , servaddrservaddr;;

listenfdlistenfd = = Socket(AF_INETSocket(AF_INET, SOCK_STREAM, 0);, SOCK_STREAM, 0);

bzero(&servaddrbzero(&servaddr, , sizeof(servaddrsizeof(servaddr));));servaddr.sin_familyservaddr.sin_family = AF_INET;= AF_INET;servaddr.sin_addr.s_addrservaddr.sin_addr.s_addr = = htonl(htonl(INADDR_ANYINADDR_ANY););servaddr.sin_portservaddr.sin_port = = htons(htons(SERV_PORTSERV_PORT););

Bind(listenfdBind(listenfd, (SA *) &, (SA *) &servaddrservaddr, , sizeof(servaddrsizeof(servaddr));));

ListenListen(listenfd(listenfd, LISTENQ);, LISTENQ);

for ( ; ; ) {for ( ; ; ) {clilenclilen = = sizeof(cliaddrsizeof(cliaddr););connfdconnfd = = AcceptAccept(listenfd(listenfd, (SA *) &, (SA *) &cliaddrcliaddr, &, &clilenclilen););

if ( (if ( (childpidchildpid = = ForkFork()) == 0) {()) == 0) { /* child process *//* child process */Close(listenfdClose(listenfd);); /* close listening socket *//* close listening socket */str_echo(connfdstr_echo(connfd);); /* process the request *//* process the request */exit(0);exit(0);

}}Close(connfdClose(connfd);); /* parent closes connected socket *//* parent closes connected socket */

}}}}

임의임의 주소주소

unp.h에 9877로 정의5001이상~49151이하

Page 6: Chapter05 TCP Client Server Example

66

5.3 TCP Echo Server: 5.3 TCP Echo Server: str_echostr_echo FunctionFunction

#include "#include "unp.hunp.h""

voidvoidstr_echo(intstr_echo(int sockfdsockfd)){{

ssize_tssize_t n;n;charchar buf[MAXLINEbuf[MAXLINE];];

again:again:while ( (n = while ( (n = readread(sockfd(sockfd, , bufbuf, MAXLINE)) > 0), MAXLINE)) > 0)

WritenWriten(sockfd(sockfd, , bufbuf, n);, n);

if (n < 0 && if (n < 0 && errnoerrno == EINTR)== EINTR)gotogoto again;again;

else if (n < 0)else if (n < 0)err_sys("str_echoerr_sys("str_echo: read error");: read error");

}}

Page 7: Chapter05 TCP Client Server Example

77

5.4 TCP Echo Client: 5.4 TCP Echo Client: mainmain FunctionFunction#include "#include "unp.hunp.h""

intintmain(intmain(int argcargc, char **, char **argvargv)){{

intint sockfdsockfd;;structstruct sockaddr_insockaddr_in servaddrservaddr;;

if (if (argcargc != 2)!= 2)err_quit("usageerr_quit("usage: : tcpclitcpcli <<IPaddressIPaddress>");>");

sockfdsockfd = = SocketSocket(AF_INET(AF_INET, SOCK_STREAM, 0);, SOCK_STREAM, 0);

bzero(&servaddrbzero(&servaddr, , sizeof(servaddrsizeof(servaddr));));servaddr.servaddr.sin_familysin_family = = AF_INETAF_INET;;servaddr.servaddr.sin_portsin_port = = htons(SERV_PORThtons(SERV_PORT););Inet_pton(Inet_pton(AF_INETAF_INET, , argv[1]argv[1], , &&servaddr.sin_addrservaddr.sin_addr););

ConnectConnect(sockfd(sockfd, (SA *) &, (SA *) &servaddrservaddr, , sizeof(servaddrsizeof(servaddr));));

str_clistr_cli(stdin(stdin, , sockfdsockfd);); /* do it all *//* do it all */

exit(0);exit(0);}}

Page 8: Chapter05 TCP Client Server Example

88

5.5 TCP Echo Client: 5.5 TCP Echo Client: str_clistr_cli FunctionFunction#include "#include "unp.hunp.h""

voidvoidstr_cli(FILEstr_cli(FILE **fpfp, , intint sockfdsockfd)){{

charchar sendline[MAXLINEsendline[MAXLINE], ], recvline[MAXLINErecvline[MAXLINE];];

while (while (FgetsFgets(sendline(sendline, MAXLINE, , MAXLINE, fpfp) != NULL) {) != NULL) {

WritenWriten(sockfd(sockfd, , sendlinesendline, , strlen(sendlinestrlen(sendline));));

if (if (ReadlineReadline(sockfd(sockfd, , recvlinerecvline, MAXLINE) == 0), MAXLINE) == 0)err_quit("str_clierr_quit("str_cli: server terminated prematurely");: server terminated prematurely");

FputsFputs(recvline(recvline, , stdoutstdout););}}

}}

Page 9: Chapter05 TCP Client Server Example

99

서버와서버와 클라이언트간클라이언트간 연결연결 및및 데이터데이터 전송전송 과정과정

Connect

Server Client

Accept

SYN

ACK, SYN

ACK

wait_for_connect wait_for_connect

ESTABLISHEDESTABLISHED

read

writeDATA

ACK

tcp_data_wait

Page 10: Chapter05 TCP Client Server Example

1010

5.6 Normal Startup (1/4)5.6 Normal Startup (1/4)

서버서버 시작시작

Page 11: Chapter05 TCP Client Server Example

1111

5.6 Normal Startup (2/4)5.6 Normal Startup (2/4)

서버의서버의 LISTEN LISTEN 상태상태 확인확인

Page 12: Chapter05 TCP Client Server Example

1212

5.6 Normal Startup (3/4)5.6 Normal Startup (3/4)

클라이언트클라이언트 시작시작

Page 13: Chapter05 TCP Client Server Example

1313

5.6 Normal Startup (4/4)5.6 Normal Startup (4/4)

서버서버//클라이언트클라이언트 간간 연결연결 확인확인

Page 14: Chapter05 TCP Client Server Example

1414

5.7 Normal Termination (1/2)5.7 Normal Termination (1/2)Normal termination of client and serverNormal termination of client and server

1.1. 클라이언트클라이언트 프로그램에서프로그램에서 EOF EOF 문자문자((control+Dcontrol+D))를를 입력하면입력하면, , fgetsfgets가가 null null 포포인터를인터를 리턴함으로써리턴함으로써, , str_clistr_cli 함수가함수가 리턴된다리턴된다..

2.2. main main 프로그램에서프로그램에서 str_clistr_cli 함수를함수를 리턴받으면리턴받으면 exitexit 함수를함수를 호출하고호출하고 클라이언클라이언트트 프로그램은프로그램은 종료된다종료된다..

3.3. 이이 때때, , 오픈된오픈된 모든모든 descriptordescriptor들은들은 closeclose되고되고, , 클라이언트클라이언트 소켓은소켓은 커널에서커널에서closeclose한다한다. . 커널에서는커널에서는 서버에게서버에게 FINFIN을을 보내고보내고, , 서버는서버는 ACKACK를를 보냄으로써보냄으로써 클클라이언트라이언트 프로그램이프로그램이 종료된다종료된다. . 이이 때때, , 서버서버 소켓은소켓은 CLOSE_WAIT CLOSE_WAIT 상태가상태가 되되고고, , 클라이언트클라이언트 소켓은소켓은 FIN_WAIT_1FIN_WAIT_1 상태이다상태이다..

4.4. 서버는서버는 FINFIN을을 수신하면수신하면, , readlinereadline 함수는함수는 00을을 리턴하고리턴하고, , str_clistr_cli 함수는함수는 서버서버Child Child 프로세스의프로세스의 mainmain으로으로 리턴하고리턴하고

5.5. exitexit 함수를함수를 호출하여호출하여 서버의서버의 자식자식 프로세스는프로세스는 종료된다종료된다..6.6. 서버의서버의 자식자식 프로세스가프로세스가 종료될종료될 때때, , 서버의서버의 자식자식 프로세스에프로세스에 있는있는 모든모든 오픈된오픈된

descriptordescriptor가가 closeclose되고되고, TCP , TCP 접속이접속이 끊기면서끊기면서 클라이언트클라이언트 소켓은소켓은TIME_WAITTIME_WAIT 상태가상태가 된다된다..

7.7. 마지막으로마지막으로, , 서버의서버의 자식자식 프로세스가프로세스가 종료될종료될 때때 SIGCHLDSIGCHLD 시그널을시그널을 부모부모 프프로세스에게로세스에게 보낸다보낸다..

본본 프로그램의프로그램의 예제에서는예제에서는 부모부모 프로세스에서프로세스에서 SIGCHLD SIGCHLD 시그널을시그널을 처리처리하지하지 않기않기 때문에때문에 자식자식 프로세스는프로세스는 좀비좀비 상태가상태가 된다된다..

Page 15: Chapter05 TCP Client Server Example

1515

5.7 Normal Termination (2/2)5.7 Normal Termination (2/2)

자식자식 프로세스의프로세스의 좀비좀비 상태상태 확인확인

Page 16: Chapter05 TCP Client Server Example

1616

5.8 POSIX Signal Handling (1/6)5.8 POSIX Signal Handling (1/6)

POSIX (Portable Operating System Interface)POSIX (Portable Operating System Interface)란란??운영체제의운영체제의 공통적인공통적인 규약을규약을 규정하고규정하고 있는있는표준이다표준이다..

상호상호 운용성운용성 증대증대..

Page 17: Chapter05 TCP Client Server Example

1717

5.8 POSIX Signal Handling (2/6)5.8 POSIX Signal Handling (2/6)

A signal is a notification to a process that an event A signal is a notification to a process that an event has occurred.has occurred.Signals are sometimes called Signals are sometimes called software interrupts.software interrupts.Signals usually occur Signals usually occur asynchronously.asynchronously.

By this we mean that a process doesnBy this we mean that a process doesn’’t know ahead of time t know ahead of time exactly when a signal will occur.exactly when a signal will occur.

Signals can be sentSignals can be sentBy By one process one process toto another processanother process (or to itself)(or to itself)By By the kernel the kernel toto a processa process

Page 18: Chapter05 TCP Client Server Example

1818

5.8 POSIX Signal Handling (3/6)5.8 POSIX Signal Handling (3/6)

The The SIGCHLDSIGCHLD signal that we described at the signal that we described at the end of the previous section is one that is sent end of the previous section is one that is sent by the kernel whenever a process terminates, by the kernel whenever a process terminates, to the parent of the terminating process.to the parent of the terminating process.Every signal has a Every signal has a dispositiondisposition, which is also , which is also called the action is called the action associated called the action is called the action associated with the signal.with the signal.

Page 19: Chapter05 TCP Client Server Example

1919

5.8 POSIX Signal Handling (4/6)5.8 POSIX Signal Handling (4/6)We set the disposition of a signal by calling the We set the disposition of a signal by calling the sigactionsigactionfunction and we have three choices for the disposition:function and we have three choices for the disposition:

We can provide a function that is called whenever a specific sigWe can provide a function that is called whenever a specific signal nal occurs. This function is called a occurs. This function is called a signal handlersignal handler and this action is called and this action is called catchingcatching a signal. The two signals a signal. The two signals SIGKILLSIGKILL and and SIGSTOPSIGSTOP cannot be cannot be caught.caught.

•• Out function is called with a signal integer argument that is thOut function is called with a signal integer argument that is the signal e signal number and the function returns nothing.number and the function returns nothing.

•• Its function prototype is thereforeIts function prototype is thereforevoid void handlerhandler(int(int signosigno););

We can We can ignoreignore a signal by setting its disposition to a signal by setting its disposition to SIG_IGNSIG_IGN. The two . The two signals signals SIGKILLSIGKILL and and SIGSTOPSIGSTOP cannot be ignored.cannot be ignored.We can set the We can set the defaultdefault disposition for a signal by setting its disposition disposition for a signal by setting its disposition to to SIG_DFLSIG_DFL. The default is normally to terminate a process on receipt . The default is normally to terminate a process on receipt of a signal, with certain signals also generating a core image oof a signal, with certain signals also generating a core image of the f the process in its current working directory.process in its current working directory.

Page 20: Chapter05 TCP Client Server Example

2020

5.8 POSIX Signal Handling (5/6)5.8 POSIX Signal Handling (5/6)

signalsignal FunctionFunctionThe POSIX way to establish the disposition of a signal is to The POSIX way to establish the disposition of a signal is to call the call the sigactionsigaction function.function.An easier way to set the disposition of a signal is to call the An easier way to set the disposition of a signal is to call the signalsignal function.function.But, But, signalsignal is an historical function that predates POSIX.is an historical function that predates POSIX.The solution is to define our own function named The solution is to define our own function named signalsignalthat just calls the POSIX that just calls the POSIX sigactionsigaction function.function.This provides a simple interface with the desired POSIX This provides a simple interface with the desired POSIX semantics.semantics.

Page 21: Chapter05 TCP Client Server Example

2121

5.8 POSIX Signal Handling (6/6)5.8 POSIX Signal Handling (6/6)

signalsignal function that calls the POSIX function that calls the POSIX sigactionsigaction functionfunction

#include "#include "unp.hunp.h""

SigfuncSigfunc **signal(intsignal(int signosigno, , SigfuncSigfunc **funcfunc)){{

structstruct sigactionsigaction act, act, oactoact;;

act.act.sa_handlersa_handler = = funcfunc;;sigemptysetsigemptyset(&act.(&act.sa_masksa_mask););act.act.sa_flagssa_flags = = 00;;if (if (signosigno == == SIGALRMSIGALRM) {) {

##ifdefifdef SA_INTERRUPTSA_INTERRUPTact.act.sa_flagssa_flags |= SA_INTERRUPT;|= SA_INTERRUPT; /* SunOS 4.x *//* SunOS 4.x */

##endifendif} else {} else {

##ifdefifdef SA_RESTARTSA_RESTARTact.act.sa_flagssa_flags |= SA_RESTART;|= SA_RESTART; /* SVR4, 44BSD *//* SVR4, 44BSD */

##endifendif}}if (if (sigaction(signosigaction(signo, &act, &, &act, &oactoact) < 0)) < 0)

return(SIG_ERRreturn(SIG_ERR););return(return(oact.sa_handleroact.sa_handler););

}

typedef void Sigfunc(int);

void (*signal(int signo, void (*func)(int)))(int);

Sigfunc *signal(int signo, Sigfunc *func);

Sigfunc 함수 원형

}

Page 22: Chapter05 TCP Client Server Example

2222

5.9 Handling 5.9 Handling SIGCHLDSIGCHLD Signals (1/4)Signals (1/4)

The purpose of the zombie state is to The purpose of the zombie state is to maintain maintain informationinformation about the child for the parent to fetch at about the child for the parent to fetch at some later time.some later time.

process ID of the child, termination status, information on process ID of the child, termination status, information on the resource utilization of the the resource utilization of the child(CPUchild(CPU time, memory, time, memory, etc.).etc.).

If a process terminates, and that process has children If a process terminates, and that process has children in the zombie state, the parent process ID of all the in the zombie state, the parent process ID of all the zombie children is set to 1(the zombie children is set to 1(the initinit process), which process), which will inherit the children and clean them will inherit the children and clean them up(i.eup(i.e., ., initinitwill wait for them, which removes the zombie).will wait for them, which removes the zombie).

Page 23: Chapter05 TCP Client Server Example

2323

5.9 Handling 5.9 Handling SIGCHLDSIGCHLD Signals (2/4)Signals (2/4)

Handling zombiesHandling zombiesObviously we do not want to leave zombies around.Obviously we do not want to leave zombies around.They take up space in the kernel and eventually we They take up space in the kernel and eventually we can run out of process.can run out of process.Whenever we Whenever we forkfork children, we must children, we must waitwait for them for them to prevent them from becoming zombies.to prevent them from becoming zombies.To do this, we establish a signal handler to catch To do this, we establish a signal handler to catch SIGCHLDSIGCHLD, and within the handler, we call , and within the handler, we call waitwait..

Page 24: Chapter05 TCP Client Server Example

2424

5.9 Handling 5.9 Handling SIGCHLDSIGCHLD Signals (3/4)Signals (3/4)

Version of Version of SIGCHLDSIGCHLD signal handler that calls signal handler that calls waitwait#include "#include "unp.hunp.h""

voidvoidsig_chld(intsig_chld(int signosigno)){{

pid_tpid_t pidpid;;intint stat;stat;

pidpid = = waitwait(&stat(&stat););printf("childprintf("child %d terminated%d terminated\\n", n", pidpid););return;return;

}}

Page 25: Chapter05 TCP Client Server Example

2525

5.9 Handling 5.9 Handling SIGCHLDSIGCHLD Signals (4/4)Signals (4/4)

zombie zombie 상태상태 처리처리 결과결과

Page 26: Chapter05 TCP Client Server Example

2626

5.10. 5.10. waitwait and and waitpidwaitpid Functions (1/6)Functions (1/6)

In Figure 5.7, we called the In Figure 5.7, we called the waitwait function to function to handle the terminated child.handle the terminated child.Difference between Difference between waitwait and and waitpidwaitpidinclude <sys/include <sys/wait.hwait.h>>

pid_tpid_t waitwait(int(int **statlocstatloc););pid_tpid_t waitpidwaitpid(pid_t(pid_t pidpid, , intint **statlocstatloc, , intint optionsoptions););

Page 27: Chapter05 TCP Client Server Example

2727

5.10. 5.10. waitwait and and waitpidwaitpid Functions (2/6)Functions (2/6)

waitwait FunctionFunctionIf there are no terminated children for the process calling If there are no terminated children for the process calling waitwait, but the process has one or more children that are still , but the process has one or more children that are still executing, then executing, then waitwait blocks until the first of the existing blocks until the first of the existing children terminates.children terminates.

waitpidwaitpid FunctionFunctionwaitpidwaitpid gives us more control over which process to wait gives us more control over which process to wait for and whether or not to block.for and whether or not to block.

•• First, the First, the pidpid argument lets us specify the process ID that we want argument lets us specify the process ID that we want to wait to wait for.to wait to wait for.

A value of A value of --1 says to wait for the first of our children to terminate.1 says to wait for the first of our children to terminate.•• The The optionsoptions argument lets us specify additional options.argument lets us specify additional options.

The most common option is The most common option is WNOHANGWNOHANG..

Page 28: Chapter05 TCP Client Server Example

2828

5.10. 5.10. waitwait and and waitpidwaitpid Functions (3/6)Functions (3/6)

Page 29: Chapter05 TCP Client Server Example

2929

5.10. 5.10. waitwait and and waitpidwaitpid Functions (4/6)Functions (4/6)

It is this delivery of multiple occurrences of the same It is this delivery of multiple occurrences of the same signal that causes that problem we about to see.signal that causes that problem we about to see.

Page 30: Chapter05 TCP Client Server Example

3030

5.10. 5.10. waitwait and and waitpidwaitpid Functions (5/6)Functions (5/6)

Final (correct) version of Final (correct) version of sig_chldsig_chld function that calls function that calls waitpidwaitpid..

#include#include ""unp.hunp.h""

voidvoidsig_chld(intsig_chld(int signosigno)){{

pid_tpid_t pidpid;;intint stat;stat;

while ( (while ( (pidpid = = waitpidwaitpid((--1, &stat, 1, &stat, WNOHANGWNOHANG)) > 0))) > 0)printf("childprintf("child %d terminated%d terminated\\n", n", pidpid););

return;return;}}

Page 31: Chapter05 TCP Client Server Example

3131

5.10. 5.10. waitwait and and waitpidwaitpid Functions (6/6)Functions (6/6)

The purpose of this section has been to The purpose of this section has been to demonstrate three scenarios that we can demonstrate three scenarios that we can encounter with network programming.encounter with network programming.

1.1. We must catch the We must catch the SIGCHLDSIGCHLD signal when signal when forkforking child processes.ing child processes.

2.2. We must handle interrupted system calls when We must handle interrupted system calls when we catch signals.we catch signals.

3.3. A A SIGCHLDSIGCHLD handler must be coded correctly handler must be coded correctly using using waitpidwaitpid to prevent any zombies from being to prevent any zombies from being left around.left around.

Page 32: Chapter05 TCP Client Server Example

3232

5.11 Connection Abort before accept Returns (1/2)5.11 Connection Abort before accept Returns (1/2)

Receiving an RST for an ESTABLISHED Receiving an RST for an ESTABLISHED connection before accept is called.connection before accept is called.

Page 33: Chapter05 TCP Client Server Example

3333

5.11 Connection Abort before accept Returns (2/2)5.11 Connection Abort before accept Returns (2/2)

커넥션이커넥션이 취소된취소된 경우경우 어떤어떤 일이일이 발생하는발생하는가는가는 구현에구현에 따라따라 다르다다르다..

BerkeleyBerkeley--derived implementations: derived implementations: 커널커널 내부에내부에서서 모두모두 처리처리, , 서버는서버는 모름모름..SVR4 implementations: SVR4 implementations: EPROTO(EPROTO(““protocolprotocolerrorerror””))를를 가진가진 errnoerrno를를 리턴리턴..POSIX: ECONNABORTED POSIX: ECONNABORTED 에러로에러로 규정규정..

Page 34: Chapter05 TCP Client Server Example

3434

5.12 Termination of Server Process (1/10)5.12 Termination of Server Process (1/10)

We will now start our client/server and kill the We will now start our client/server and kill the server child process.server child process.This simulates the crashing of the server This simulates the crashing of the server process, so we can see what happens to the process, so we can see what happens to the client.client.

Page 35: Chapter05 TCP Client Server Example

3535

5.12 Termination of Server Process (2/10)5.12 Termination of Server Process (2/10)

Step 1Step 1Start the server and client and type one line to the Start the server and client and type one line to the client to verify that all is okay.client to verify that all is okay.

Server (tcpserv04.c) Client (tcpcli04.c)

Page 36: Chapter05 TCP Client Server Example

3636

5.12 Termination of Server Process (3/10)5.12 Termination of Server Process (3/10)

Step 2Step 2Find the process ID of the server child and Find the process ID of the server child and killkill it.it.

Page 37: Chapter05 TCP Client Server Example

3737

5.12 Termination of Server Process (4/10)5.12 Termination of Server Process (4/10)

Step 3Step 3The The SIGCHLDSIGCHLD signal is sent to the server parent signal is sent to the server parent and handled correctly.and handled correctly.

Page 38: Chapter05 TCP Client Server Example

3838

5.12 Termination of Server Process (5/10)5.12 Termination of Server Process (5/10)

Step 4Step 4Nothing happens at the client. The client TCP Nothing happens at the client. The client TCP receives the receives the FINFIN from the server TCP and from the server TCP and responds with an responds with an ACKACK, but the problem is that the , but the problem is that the client process is blocked in the call to client process is blocked in the call to fgetsfgets waiting waiting for a line from the terminal.for a line from the terminal.

Page 39: Chapter05 TCP Client Server Example

3939

5.12 Termination of Server Process (6/10)5.12 Termination of Server Process (6/10)

Step 5Step 5Running Running netstatnetstat at this point shows the stat of the at this point shows the stat of the sockets.sockets.

Server (tcpserv04.c)Client (tcpcli04.c)

Page 40: Chapter05 TCP Client Server Example

4040

5.12 Termination of Server Process (7/10)5.12 Termination of Server Process (7/10)

Step 6 (1/2)Step 6 (1/2)We can still type a line of input to the client. Here We can still type a line of input to the client. Here is what happens at the client starting from Step 1:is what happens at the client starting from Step 1:

Page 41: Chapter05 TCP Client Server Example

4141

5.12 Termination of Server Process (8/10)5.12 Termination of Server Process (8/10)

Step 6 (2/2)Step 6 (2/2)When we type When we type ““hihi””, , str_clistr_cli calls calls writenwriten and the client TCP and the client TCP sends the data to the server.sends the data to the server.This is allowed by TCP because the receipt of the This is allowed by TCP because the receipt of the FINFIN by by the client TCP only indicates that the server process has the client TCP only indicates that the server process has closed its end of the connection and will not be sending any closed its end of the connection and will not be sending any more data.more data.The receipt of the The receipt of the FINFIN does not tell the client TCP that the does not tell the client TCP that the server process has terminated.server process has terminated.When the server TCP receives the data from the client, it When the server TCP receives the data from the client, it response with an response with an RSTRST since the process that had that socket since the process that had that socket open has terminated.open has terminated.

Page 42: Chapter05 TCP Client Server Example

4242

5.12 Termination of Server Process (9/10)5.12 Termination of Server Process (9/10)

Step 7Step 7The client process will not see the RST because it The client process will not see the RST because it calls calls readlinereadline immediately the FIN that was immediately the FIN that was received in Step 2.received in Step 2.Our client is not expecting to receive an EOF at Our client is not expecting to receive an EOF at this point so it quits with the error message this point so it quits with the error message ““server server terminated prematurelyterminated prematurely..””

Page 43: Chapter05 TCP Client Server Example

4343

5.12 Termination of Server Process (10/10)5.12 Termination of Server Process (10/10)

Step 8Step 8When the client terminates, all its open descriptors are When the client terminates, all its open descriptors are closed.closed.

※※The problem in this example is that the client is The problem in this example is that the client is blocked in the call to blocked in the call to fgetsfgets when the FIN arrives on when the FIN arrives on the socket.the socket.

※※The client is really working with two descriptorsThe client is really working with two descriptors--the the socket and the user inputsocket and the user input--and instead of blocking on and instead of blocking on input from only one of the two sources, it should input from only one of the two sources, it should block on input from either source.block on input from either source.

Page 44: Chapter05 TCP Client Server Example

4444

5.13 5.13 SIGPIPESIGPIPE Signal (1/4)Signal (1/4)

What happens if the client ignores the error return What happens if the client ignores the error return from from readlinereadline and writes more data to the server?and writes more data to the server?

For example, if the client needs to perform two writes to For example, if the client needs to perform two writes to the server before reading anything back, with the first write the server before reading anything back, with the first write eliciting the eliciting the RSTRST..

The rule that applies is:The rule that applies is:When a process writes to a socket that has received an When a process writes to a socket that has received an RSTRST, , the the SIGPIPESIGPIPE signal is sent to the process.signal is sent to the process.The default action of this signal is to terminate the process.The default action of this signal is to terminate the process.So the process must catch the signal to avoid being So the process must catch the signal to avoid being involuntarily terminated.involuntarily terminated.

Page 45: Chapter05 TCP Client Server Example

4545

5.13 5.13 SIGPIPESIGPIPE Signal (2/4)Signal (2/4)To see what happens with SIGPIPE, we modify our client as To see what happens with SIGPIPE, we modify our client as shown in this code.shown in this code.

#include "#include "unp.hunp.h""

voidvoidstr_cli(FILEstr_cli(FILE **fpfp, , intint sockfdsockfd)){{

char char sendline[MAXLINEsendline[MAXLINE], ], recvline[MAXLINErecvline[MAXLINE];];

while (while (Fgets(sendlineFgets(sendline, MAXLINE, , MAXLINE, fpfp) != NULL) {) != NULL) {

WritenWriten(sockfd(sockfd, , sendlinesendline, 1);, 1);sleep(1);sleep(1);WritenWriten(sockfd(sockfd, sendline+1, strlen(sendline), sendline+1, strlen(sendline)--1);1);

if (if (Readline(sockfdReadline(sockfd, , recvlinerecvline, MAXLINE) == 0), MAXLINE) == 0)err_quit("str_clierr_quit("str_cli: server terminated prematurely");: server terminated prematurely");

Fputs(recvlineFputs(recvline, , stdoutstdout););}}

}}

Page 46: Chapter05 TCP Client Server Example

4646

5.13 5.13 SIGPIPESIGPIPE Signal (3/4)Signal (3/4)

If we run the client on our Linux host, we get:If we run the client on our Linux host, we get:

linuxlinux % % tcpcli11 127.0.0.1tcpcli11 127.0.0.1hi therehi therehi therehi there

byebyeBroken pipeBroken pipe

Page 47: Chapter05 TCP Client Server Example

4747

5.13 5.13 SIGPIPESIGPIPE Signal (4/4)Signal (4/4)

Page 48: Chapter05 TCP Client Server Example

4848

5.14 Crashing of Server Host5.14 Crashing of Server Host

This scenario will test to see what happens when the This scenario will test to see what happens when the server host crashes.server host crashes.

1.1. When the server host crashes, nothing is sent out on the When the server host crashes, nothing is sent out on the existing network connections.existing network connections.

2.2. We type a line of input to the client, it is We type a line of input to the client, it is writenwriten by by writenwriten, , and is sent by the client TCP as a data segment. The client and is sent by the client TCP as a data segment. The client then blocks in the call to then blocks in the call to readlinereadline, waiting for the echoed , waiting for the echoed reply.reply.

3.3. We will see the client TCP continually retransmitting the We will see the client TCP continually retransmitting the data segment, trying to receive an ACK from the server.data segment, trying to receive an ACK from the server.

4.4. When the client TCP When the client TCP fanallyfanally gives up, an error is returned gives up, an error is returned to the client process.to the client process.

Page 49: Chapter05 TCP Client Server Example

4949

5.15 Crashing and Rebooting of Server Host5.15 Crashing and Rebooting of Server Host

In this scenario, we will establish a connection between the In this scenario, we will establish a connection between the client and server and then assume the server host crashes client and server and then assume the server host crashes and reboots.and reboots.

1.1. Start the server and then the client.Start the server and then the client.2.2. The server host crashes and reboots.The server host crashes and reboots.3.3. Type a line of input to the client, which is sent as a TCP data Type a line of input to the client, which is sent as a TCP data

segment to the server host.segment to the server host.4.4. When the server host reboots after crashing, its TCP loses all When the server host reboots after crashing, its TCP loses all

information about connections that existed before the crash. information about connections that existed before the crash. Therefore, the server TCP responds to the received data segment Therefore, the server TCP responds to the received data segment from the client with an from the client with an RSTRST..

5.5. Client is blocked in the call to Client is blocked in the call to readlinereadline when the when the RSTRST is received, is received, causing causing readlinereadline to return the error to return the error ECONNRESETECONNRESET..

Page 50: Chapter05 TCP Client Server Example

5050

5.16 Shutdown of Server Host5.16 Shutdown of Server Host

호스트에서호스트에서 서버서버 프로세스가프로세스가 동작동작 중일중일 때때 서버서버호스트를호스트를 운영자가운영자가 끄면끄면 어떻게어떻게 되는가되는가

유닉스유닉스 시스템이시스템이 종료할종료할 때는때는 보통보통 init init 프로세스가프로세스가SIGTERMSIGTERM 시그널을시그널을 모든모든 프로세스에게프로세스에게 보내고보내고, , 일정일정시간시간(5~20(5~20초초) ) 동안동안 기다린다기다린다..일정일정 시간시간 후에도후에도 여전히여전히 실행실행 중인중인 모든모든 프로세스로프로세스로SIGKILLSIGKILL 시그널을시그널을 보낸다보낸다..만약만약 서버가서버가 SIGTERMSIGTERM을을 캐치하여캐치하여 종료하지종료하지 못하면못하면SIGKILLSIGKILL 시그널에시그널에 의해의해 종료된다종료된다..클라이언트에서클라이언트에서 서버서버 프로세스의프로세스의 종료를종료를 곧바로곧바로 감지감지하기하기 위해서는위해서는 selectselect나나 pollpoll 함수를함수를 사용해야사용해야 한다한다..

Page 51: Chapter05 TCP Client Server Example

5151

5.17 Summary of TCP Example5.17 Summary of TCP Example

클라이언트클라이언트 관점관점

Page 52: Chapter05 TCP Client Server Example

5252

5.17 Summary of TCP Example5.17 Summary of TCP Example

서버서버 관점관점

Page 53: Chapter05 TCP Client Server Example

5353

5.18 Data Format5.18 Data Format데이터데이터 스트링스트링 송송··수신수신

#include "#include "unp.hunp.h""

voidvoidstr_echo(intstr_echo(int sockfdsockfd)){{

long arg1, arg2;long arg1, arg2;ssize_tssize_t n;n;char char line[MAXLINEline[MAXLINE];];

for ( ; ; ) {for ( ; ; ) {if ( (n = if ( (n = Readline(sockfdReadline(sockfd, line, MAXLINE)) == 0), line, MAXLINE)) == 0)

return;return; /* connection closed by other end *//* connection closed by other end */

if (if (sscanf(linesscanf(line, "%, "%ld%ldld%ld", &arg1, &arg2) == 2)", &arg1, &arg2) == 2)snprintf(linesnprintf(line, , sizeof(linesizeof(line), "%ld), "%ld\\n", arg1 + arg2);n", arg1 + arg2);

elseelsesnprintf(linesnprintf(line, , sizeof(linesizeof(line), "input error), "input error\\n");n");

n = n = strlen(linestrlen(line););Writen(sockfdWriten(sockfd, line, n);, line, n);

}}}}

Page 54: Chapter05 TCP Client Server Example

5454

5.18 Data Format5.18 Data Format이진이진 데이터데이터 송송··수신수신

#include "#include "unp.hunp.h""#include "#include "sum.hsum.h""

voidvoidstr_cli(FILEstr_cli(FILE **fpfp, , intint sockfdsockfd)){{

char char sendline[MAXLINEsendline[MAXLINE];];structstruct argsargs argsargs;;structstruct result result resultresult;;

while (while (Fgets(sendlineFgets(sendline, MAXLINE, , MAXLINE, fpfp) != NULL) {) != NULL) {

if (if (sscanf(sendlinesscanf(sendline, "%, "%ld%ldld%ld", &args.arg1, &args.arg2) != 2) {", &args.arg1, &args.arg2) != 2) {printf("invalidprintf("invalid input: %s", input: %s", sendlinesendline););continue;continue;

}}Writen(sockfdWriten(sockfd, &, &argsargs, , sizeof(argssizeof(args));));

if (if (Readn(sockfdReadn(sockfd, &result, , &result, sizeof(resultsizeof(result)) == 0))) == 0)err_quit("str_clierr_quit("str_cli: server terminated prematurely");: server terminated prematurely");

printf("%ldprintf("%ld\\nn", ", result.sumresult.sum););}}

}}