2011-04-12 46 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);