2011-04-12 34 views
2

当我使用Web浏览器测试我的程序时,我可以写入套接字/ FD就好了,所以我决定循环并切断连接,并注意到一个问题。当套接字不可用时,send()能够关闭整个程序。我认为问题在于这个程序陷入了一个陷阱22并且自己关闭了。所以我将套接字设置为不阻塞。不用找了。任何想法为什么发生这种情况?send()问题

else if (b->temp_socket_list[read].revents & POLLOUT) { 
    printf ("#Write#\n"); 
    char *done = "Done!"; 
    int sent = send (sock, done, 5, 0); 
    printf ("end\n", sent); 
} 
+5

发布一些代码演示行为。 – NPE 2011-04-12 20:34:09

+2

此外,运行'strace'程序,以便我们可以看到真正发生的事情。 – 2011-04-12 20:37:21

+0

@Roland +1。这是我能够找出一个过程在几个月前获得SIGPIPE的唯一途径。它似乎在系统初始化后不久就死掉了。 – Jeff 2011-04-12 20:49:58

回答

5

这可能是由于SIGPIPE信号的默认操作。要忽略此信号,请使用类似如下的代码:

signal(SIGPIPE, SIG_IGN); 

套接字错误将作为套接字函数的返回值报告,而不是信号。

+0

请注意,你不能从库代码中做到这一点,它不应该修改调用者的信号处置,至少不是没有记录它并包括一个大的警告。但是,如果您使用sendto而不是send,则可以指定一个标志,指示您不希望生成SIGPIPE。我相信还有一个涉及'setsockopt'的解决方案,并且使用'pthread_sigmask'和'sigtimedwait'来阻止和清除挂起的'SIGPIPE'。 – 2011-04-12 21:53:43

3

作为忽略SIGPIPE的替代方案,this post在如何避免它们方面有一些很好的答案。

+0

+1替代解决方案。 – 2011-04-12 22:04:49

3

这是哪个平台?

在UNIX上,在某些情况下,当连接断开时(SIGPIPE),这会在默认情况下终止程序时发出信号...解决方案是为SIGPIPE安装一个信号处理程序,该程序不执行任何操作。

0

试试这个:

sigset_t set, oldset; 
sigemptyset(&set); 
sigaddset(&set, SIGPIPE); 
pthread_sigmask(SIG_BLOCK, &set, &oldset); 
/* use send all you like here */ 
sigtimedwait(&set, 0, (struct timespec [1]){0}); 
pthread_sigmask(SIG_SETMASK, &oldset, 0); 

我不是100%肯定它的工作原理,但我相信它应该,如果它是正确的,那么它是可以从库中的代码中使用不搞乱国家的解决方案的调用者或其他可能使用信号的线程。

还要注意的是,如果程序(或者甚至只是当前线程)并不想利用SIGPIPE,你可以在此通过正要离开SIGPIPE永久阻止简化了很多:

sigset_t set; 
sigemptyset(&set); 
sigaddset(&set, SIGPIPE); 
pthread_sigmask(SIG_BLOCK, &set, &oldset);