gpt4 book ai didi

c - sigpipe c 服务器/客户端 - 程序在哪里重新启动?

转载 作者:行者123 更新时间:2023-11-30 15:28:40 25 4
gpt4 key购买 nike

我有一个客户端/服务器程序,现在我想处理信号。当客户端关闭连接时(例如,如果我关闭终端),服务器必须处理 SIGPIPE,对吗?我想实现这样的事情。可能吗?

服务器.c:

void function(){
printf("...");
read(socket,buff,size);
//IF THE CLIENT CLOSES, THE SERVER RECEIVES A SIGPIPE
...the resting part of the scheduled code should be ignored if sigpipe is received, and the program should begin from where I wrote on the handler of the sigpipe...
printf("not working"); //this should be ignored, but it's printed 2 times immediatly, and when I've finished the actions indicated in the function by the handler, it prints it another time, because the program counter restarts from here...
}

void sigpipehandler(){
close(socket);
main(); //I'd like that the program restarts from the main when I've received a SIGPIPE. It restarts from the main, but only after having printed "not working" two times...
}

int main(){
sigPipe.sa_sigaction = &sigpipehandler;
sigPipe.sa_flags = SA_SIGINFO;
sigaction(SIGPIPE, &sigpipehandler, NULL);
...code...
}

最佳答案

将评论转换为答案。

请注意,只有当您写入没有进程且管道读取端打开的管道时,您才会收到 SIGPIPE。当您从没有进程且管道写入端打开的管道中读取数据时,您会得到 EOF(零字节读取)。

So, if I change the read() with a write() in the example. How can I handle the SIGPIPE?

最简单的是忽略 SIGPIPE (signal(SIGPIPE, SIG_IGN)),然后监视 write() 的返回值。如果它返回 -1 且 errno 设置为 EINTR,您可以假设您被某些信号中断,很可能是 SIGPIPE,特别是如果您没有任何其他信号处理集。当然,无论如何,您都应该查看 write()read() 的返回值。

或者,如果您想要一个显式的 SIGPIPE 处理程序,那么您绝对不希望从信号处理程序中递归调用 main() 。您可以在 main() 中编写一个循环,并让信号处理程序设置一个您在循环中测试的标志。根据标准 C,在信号处理程序中您可以做的唯一事情就是修改变量或退出。

static volatile sigatomic_t sig_recvd = 0;
static int sock_fd = -1;

void sigpipehandler(int signum)
{
close(sock_fd);
sock_fd = -1;
sig_recvd = signum;
}

int main(void)
{
sigPipe.sa_sigaction = &sigpipehandler;
sigPipe.sa_flags = SA_SIGINFO;
sigemptyset(&sigPipe.sa_mask);
sigaction(SIGPIPE, &sigpipehandler, NULL);

int done = 0;

while (!done)
{
if (sock_fd == -1)
{
if (sig_recvd != 0)
{
...report signal received...
sig_recvd = 0;
}
...(re)open socket on sock_fd...
}
...code as before - sets done = 1 when loop should terminate...
}
return 0;
}

请注意,将变量命名为与系统调用相同的名称(代码中的socket)是如履薄冰;因此,我将其重命名为 sock_fd。名为 socket 的全局变量将是一个非常糟糕的主意。

关于c - sigpipe c 服务器/客户端 - 程序在哪里重新启动?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26500951/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com