![if !IE]> <![endif]>
Connection abort before accept returns :
Similar to interrupted system call, a non fatal error occurs when the client is reset after three handshake without transfer of any packet.
After the three way handshake, 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.
What happens to aborted connection depends on the type of implementation . The Berkley derived implementation handles the aborted connection completely within the kernal and the server process never sees it. Most of the SVR4 (System V release 4) implementation returns an error to the process as the return from accept and the type of error depends on the implementation. Most implementation returns an errono EPROTO ( protocol error) but posix .1g specifies that the return must be ECONNABORTED (―software caused connection abort‖). The reason for this is that EPROTO is also returned when some fatal protocol related event occurs on the bytestream. Receiving the same error EPROTO by the server makes it difficult to decide whether to call accept again or not. IN case of ECONNABORTED error, the4 server ignores the error and just call accept again.
Termination of Server Process:
After starting client – server, the child process is killed at the server ( kill the child process based on the its ID ). This simulates the crashing of the server process, then what happens to client: The following steps take place.
1. We start the server and client on different hosts and type one line to the client to verify that all is OK. That line is echoed normally by the server child.
2. Identify the process ID of the server child and kill it. As part of the process termination, all open descriptors in the child are closed. This causes the FIN to by sent to the client and the client TCP responds with an ACK. This is the first half of the TCP connection termination.
3. The SIGCHLD signal is sent to the server parent and handled correctly.
4. Nothing happens at the client. The client receives the FIN from the sever TCP and responds with an ACK. But the problem is that the client process is blocked in the call to the fgets waiting for a line form the terminal.
5. When we type another line, str_cli calls written and the client TCP sends the data to the sever. This is allowed by TCP because the receipt of the FIN by the client TCP only indicates that the server process has closed its end of the connection and will not send any more data. The receipt of FIN does not tell the client that the server process has terminated (which in this case it has).
6. When the server TCP receives the data from the client, it responds with an RST since the process that had that socket open has terminated. We can verify that the RST is sent by watching the packets with tcpdump
7. But the client process will not see the RST because it calls readline immediately a after the call to writen and readline returns 0 (end of line) immediately because of the FIN that was received inIT2351-NPM/ U-2/ 12 step 2. Our client is not expecting to receive an end of line at this point so it quits with an error message server terminated prematurely.―
8. So when the client terminates ( by calling err_quit), all its open descriptors are closed.
The problem in this example is that the client blocked in the call to fgets when the FIN arrives on the socket. The client is really working with the two descriptors - the socket and the user input - and instead of blocking on input from any one of the two sources, it should block on input from either
source. This is the function of select and poll function .
When the client has more than one to write, what happens to it? That is when the FIN is received, the readline returns RST, but the second one is also written. The rule applied here is, when a process writes to a socket that has received an RST, the SIGPIPE signal is sent to the process. The default action of this signal is to terminate the process so the process must catch the signal to avoid involuntarily terminated.
If the process catches the signal and returns from the signal handler, or ignores the signal, the write operation returns EPIPE (error pipe)
void str_cli (FILE *fp, int sockfd)
char sendline[MAXLINE], recvline[MAXLINE]; while (fgets(sendline, MAXLINE, fp)!=null)
writen(sockfd, sendline, 1); sleep(1);
writen (sockfd, sendline +1, strlen (sendline)-1); if (readline()sockfd, recvline, MAXLINE==0)
err_quit (―str_cli: server terminated prematurely‖); fputs (recvline, stdout);
in the above str_cli(), the writen is called two times: the first time the first byte of data is writen to the socket, followed by a pause of 1 sec, followed by the remainder of the line. The intention is for the first writen to elicit the RST and then for the second writen to generate SIGPIPE.
We start with the client, type in one line, see that line is echoed correctly, and then terminates the server child on the server host, we then type another line, but nothing is echoed and we just get a shell Prompt. Since the default action of the SIGPIPE is to terminate the process without generating a core file, nothing is printed by the Kornshell.
The recommended way to handle SIGPIPE depends on what the application what to do when this occurs. IF there is nothing special to do, then setting the signal disposition to SIG_IGN is easy, assuming that subsequent output operations will catch the error of EPIPE and terminate.
IF special actions are needed when the signal occurs, then the signal should be caught and any desired actions can be performed in the signal handler.
If multiple sockets are in use, the delivery of the signal does not tell us which socket encountered the error. IF we need to know which write caused the error, then we must either ignore the signal or return from the signal handler and handle EPIPE from write
Copyright © 2018-2023 BrainKart.com; All Rights Reserved. Developed by Therithal info, Chennai.