5.卷1(套接字联网API)---TCP客户/服务器程序示例

本文探讨了Unix网络编程中常见的信号处理问题,包括如何正确处理慢系统调用避免EINTR错误,合理使用waitpid()函数防止僵尸进程,以及面对服务器进程终止、SIGPIPE信号等情况下的应对策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.阻塞与某个慢系统调用的进程捕获信号并返回,该系统调用可能返回EINTR错误。 
  正确处理慢系统调用 : 
	for ( ; ; ) {
		clilen = sizeof(cliaddr);
		if ( ( conndf = accpet(listenfd, (SA *)&cliaddr, &clilen) < 0 ) ) {
			if ( errno == EINTR ) {
				continue;
			} else {
				err_sys("accept error");
			}
		}
	}

2.Unix中信号不一般不排队,信号处理函数一般只执行一次。
  使用 waitpid(), 而不是 wait。waitpid 函数,指定 WNOHANG 选项,如果有
  尚未终止的子进程运行时,不要阻塞。
3.编写网络程序时,可能会遇到的3种情况:
	1.当fork子进程时,必须捕获 SIGCHILD 信号;
	2.当捕获信号时,必须处理被中断的系统调用;
	3.SIGCHILD 的信号处理函数必须被正确编写,应该使用waitpid函数以免留下僵死进程。

4.服务器进程被终止
	服务器一段先发送FIN,如果客户端再发送数据,服务器会返回一个RST,
	如果客户端read在接受 RST 之前,客户端收到一个未预期的EOF(服务器过早终止)。
	如果客户端read在接受到 RST 之后,read 返回一个 ECONNREST,"connection reset by peer", 对方复位连接错误。


5.服务端进程已经发送FIN,第一次写引发 RST。 再次写,引发 SIGPIPE 信号

6.如果服务器主机奔溃,客户端阻塞在read上,超过一定时间返回 timeout 超时或者主机不可达错误。
  这是主动发送错误才发现的,还有另外的技术。SO_KEEPALIVE套接字选项。
void sig_child(int signo)
{
	pid_t pid;
	int stat;


	while ( (pid = waitpid(-1,&stat,WNOHANG)) > 0 ) {  // 循环获取已经终止子进程的状态, WNOHANG如果有尚未终止的子进程,不阻塞
		printf("child %d terminated \n",pid);
	}
	return;
}

1.概述






处理 SIGCHLD 信号



wait 和 waitpid 函数



accpet 返回前终止:



服务器进程终止:



SIGPIPE 信号:



服务器主机崩溃:



服务器主机崩溃后重启:









评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值