2010-02-10 1 views
5

나는 유닉스 도메인 소켓을 통해 서로 연결된 두 개의 프로세스 (A와 B라고 부르 자.)로 구성된 애플리케이션을 가지고있다. 대부분의 경우 제대로 작동하지만 일부 사용자는 다음과 같은 동작을보고합니다.close() 또는 crash를 호출하지 않아도 자발적인 EPIPE 오류가 발생할 수 있습니까?

  1. A가 B에게 요청을 보냅니다. 이제 A에서 응답을 읽기 시작합니다.
  2. B가 A에게 응답을 보냅니다. 해당 write() 호출이 EPIPE 오류를 반환하고 결과적으로 B 소켓을 닫습니다(). 그러나 A는 이 아니며 소켓을 닫거나 소켓을 충돌시키지 않았습니다.
  3. A의 read() 호출은 파일 끝을 나타내는 0을 반환합니다. A는 B가 연결을 조기 종료했다고 생각합니다.

사용자는이 동작의 변화를보고, 예 :

  1. A이 부분적으로 작동 B.에 요청을 보내지 만, 전체 요청이 A의 쓰기 전송되기 전에() 호출은 EPIPE를 반환하고, 결과적으로 소켓을 close()합니다. 그러나 B는 소켓을 닫지 않았고 충돌도 발생하지 않았습니다.
  2. B가 부분 요청을 읽은 다음 갑자기 EOF를받습니다.

문제는 로컬에서이 동작을 전혀 재현 할 수 없다는 것입니다. 나는 OS X과 리눅스를 시도했다. 사용자는 주로 OS X 및 Linux와 같은 다양한 시스템에 있습니다. 나는 이미 시도하고 생각했습니다

것들 :

  • 더블 가까운() (close()를 같은 파일 기술자에 두 번 호출됩니다) 버그 : 아마 그 EBADF 오류가 발생할 것이나,하지로 나는 그들을 보지 못했다.
  • 최대 파일 설명자 제한이 증가합니다. 한 사용자가이 작업이 그를 위해 효과가 있다고보고했으며, 나머지는 그렇지 않다고보고했습니다.

그 밖의 어떤 행동을 일으킬 수 있습니까? 나는 A와 B 어느 쪽도 소켓을 너무 조기에 닫지 않는다는 것을 알고 있으며, A와 B 모두 오류를보고 할 수 있기 때문에 어느 쪽도 충돌하지 않았다는 것을 확실히 알고 있습니다. 마치 갑자기 어떤 이유로 커널이 소켓에서 플러그를 뽑기로 결정한 것과 같습니다.

답변

3

은 아마 당신은 strace를 시도해 볼 수도 있습니다 물론 the packet sniffer이다 : http://modperlbook.org/html/6-9-1-Detecting-Aborted-Connections.html

나는 당신의 문제는 여기에 설명 된 것과 관련이 있다고 가정합니다 http://blog.netherlabs.nl/articles/2009/01/18/the-ultimate-so_linger-page-or-why-is-my-tcp-not-reliable

불행히도 similar problem 자신이 있지만 주어진 조언을 통해 문제를 해결할 수 없습니다. 그러나 아마도 SO_LINGER가 당신을 위해 일할 것입니다.

+0

서버의 파일 디스크립터가 EPOLLET 플래그와 함께 epoll 큐에 추가 된 것이 틀린 것으로 판명되었습니다. – user206268

+2

정확히 내가 찾던 답변이 아니지만 링크 된 TCP 페이지는 매우 유익합니다! Archive.org는 여전히 다운 된 상태입니다. http://ia700609.us.archive.org/22/items/TheUltimateSo_lingerPageOrWhyIsMyTcpNotReliable/the-ultimate-so_linger-page-or-why-is-my-tcp-not-reliable .html – Hongli

2
  • shutdown() 은 소켓 엔드 포인트 중 하나라고되었을 수 있습니다.

  • 양쪽 그것을 상속을 위해 당신이 의도하지 않은 경우 FD_CLOEXEC (근접 온 간부) 플래그가 소켓의 파일 기술자에 설정되어 있는지 확인, 포크와 자식 프로세스를 실행할 수있는 경우

    어린이는 입니다. 그렇지 않으면 자식 프로세스 이 (실수로 또는 다른 방법으로) 소켓 연결을 조작 할 수 있습니다.

+0

감사합니다. 그러나 어느 상황도 내 프로그램에 적용 할 수 없습니다. – Hongli

0

중간에 부주의 한 방화벽이 없는지 확인합니다. 경로상의 중간 전달 노드가 RST을 전송할 수 있습니다.(. 또는 GUI cousin)에 설명 된대로 그를 추적하는 가장 좋은 방법은

+0

... UNIX 도메인 소켓에 있습니까? 이것은 로컬 전용 프로토콜입니다. – ephemient

+0

아 ... 쏘고, 나는 그것을 놓쳤다. 감사. –

관련 문제