Unix Network Programming Episode 42

这篇博客探讨了网络编程中三个关键场景:处理子进程的SIGCHLD信号、中断系统调用的处理和防止僵尸进程。通过实例展示了当accept返回非致命错误时如何重试,以及服务器进程终止时客户端的响应。当服务器进程被杀死时,TCP连接会经历半关闭状态,最终客户端因接收到RST信号而提示服务器提前终止。同时,如果忽略错误并继续写入数据,SIGPIPE信号将导致进程终止。
摘要由CSDN通过智能技术生成

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

1.We must catch the SIGCHLD signal when forking child processes.
2.We must handle interrupted system calls when we catch signals.
3.A SIGCHLD handler must be coded correctly using waitpid to prevent any zombies from being left around.

Connection Abort before ‘accept’ Returns

There is another condition similar to the interrupted system call example in the previous section that can cause accept to return a nonfatal error, in which case we should just call accept again.

Termination of Server Process

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

The following steps take place:

1.We start the server and client and type one line to the client to verify that all is okay. That line is echoed normally by the server child.
2.We find the process ID of the server child and kill it. As part of process termination, all open descriptors in the child are closed. This causes a FIN to be 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 (Figure 5.12(See 8.3.10)).
4.Nothing happens at the client. The client TCP receives the FIN from the server TCP and responds with an ACK, but the problem is that the client process is blocked in the call to fgets waiting for a line from the terminal.
5.Running netstat at this point shows the state of the sockets.
6.We can still type a line of input to the client.
7.When we type “another line,” str_cli calls writen and the client TCP sends the data to the server. 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 be sending any more data. The receipt of the FIN does not tell the client TCP that the server process has terminated (which in this case, it has).
7.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 was sent by watching the packets with tcpdump.
8.The client process will not see the RST because it calls readline immediately after the call to writen and readline returns 0 (EOF) immediately because of the FIN that was received in Step 2. Our client is not expecting to receive an EOF at this point (Figure 5.5(See 8.3.5)) so it quits with the error message “server terminated prematurely.”
9.When the client terminates (by calling err_quit in Figure 5.5(See 8.3.5)), all its open descriptors are closed.

‘SIGPIPE’ Signal

What happens if the client ignores the error return from readline and writes more data to the server? This can happen, for example, if the client needs to perform two writes to the server before reading anything back, with the first write eliciting the RST.

The rule that applies 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 being involuntarily terminated.

If the process either catches the signal and returns from the signal handler, or ignores the signal, the write operation returns EPIPE.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值