2011-04-12 5 views
2

웹 브라우저를 사용하여 프로그램을 테스트 할 때 socket/FD에 쓸 수 있기 때문에 루프를 돌리고 연결 중간 연결을 끊어서 문제를 발견했습니다. send()는 소켓을 사용할 수 없을 때 전체 프로그램을 닫을 수 있습니다. 문제는 프로그램이 캐치 22에 붙잡혀 스스로 닫히는 문제라고 생각했습니다. 그래서 소켓을 차단하지 않도록 설정했습니다. 변경 없음. 왜 이런 일이 일어 났는지에 대한 아이디어가 있습니까?send() problem

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

포스트 보여주는 몇 가지 코드를 :

또한 프로그램 (또는 단지 현재의 thread) SIGPIPE의 사용을 원하지 않는 경우, 당신은 단지 영구적으로 차단 SIGPIPE를 떠나하여이 많이를 단순화 할 수 있습니다 그 행동. – NPE

+2

그리고'strace'를 프로그램과 함께 실행하면 실제로 일어나는 일을 볼 수 있습니다. –

+0

@Roland +1. 몇 달 전에 프로세스가 SIGPIPE를 얻는 것을 알 수있는 유일한 방법이었습니다. 그것은 단순히 시스템 초기화 직후에 죽는 것처럼 보였습니다. 대체 해결책은 – Jeff

답변

5

이것은 아마도 SIGPIPE 신호의 기본 동작 때문일 수 있습니다.

signal(SIGPIPE, SIG_IGN); 

소켓 오류가 다음 반환 소켓 함수의 값보다는 신호로보고됩니다 :이 신호를 무시하려면, 같은 것을 사용합니다.

+0

라이브러리 코드에서는 호출자의 신호 처리를 수정해서는 안되며 최소한 문서화 및 큰 경고를 포함하지 않는 것이 좋습니다. 그러나 보내기보다는'sendto'를 사용하면'SIGPIPE'가 생성되지 않도록하는 플래그를 지정할 수 있습니다. 나는 또한'setsockopt'와'및''pthread_sigmask''와'sigtimedwait'를 사용하여 보류중인'SIGPIPE'를 차단하고 지우는 해결책이 있다고 믿습니다. –

3

SIGPIPE를 무시하는 대신에 this post에는이를 피하는 방법에 대한 좋은 답변이 있습니다.

+0

+1입니다. –

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 % 확실하지 않다,하지만 난 그것을해야 믿고, 그 다음 맞습니다 경우이 상태를 엉망으로하지 않고 라이브러리 코드에서 사용할 수있는 솔루션입니다 호출자 또는 기타 잠재적으로 신호를 사용하는 스레드

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