2011-01-03 10 views
54

피어 측의 소켓이 닫힐 때 깨진 파이프 오류가 발생합니다.브로큰 파이프 오류의 원인은 무엇입니까?

그러나 필자의 테스트에서 피어 사이드가 닫혀있을 때 즉각적인 '보내기'호출이 항상 깨진 파이프 오류로 이어지는 것은 아니라는 점을 지적했다.

예 : 나는 40 바이트를 보내려고하면

(필자는 동료를 죽이고 가까이도 이상 폐쇄를 호출하여 깨끗한 폐쇄를 시도) 피어 측의 소켓을 닫은 후, 다음, 내가하지 않습니다 깨진 파이프.하지만 40000 바이트를 보내려고하면 즉시 깨진 파이프 오류가 발생합니다.

깨진 파이프가 정확히 발생하고 예측할 수있는 동작은 무엇입니까?

답변

39

네트워크가 닫히는 데는 시간이 걸릴 수 있습니다. 포트를 목적지로하는 패킷이 모두 죽기 전에 총 시간은 거의 2 분 (예, 분!)입니다. 오류 조건은 어느 시점에서 발견됩니다. 작은 글씨로 시스템의 MTU 안에 있으므로 메시지는 전송 대기 중입니다. 큰 글씨로, 당신은 MTU보다 크고 시스템은 문제를 더 빨리 발견합니다. SIGPIPE 신호를 무시하면 연결이 끊어진 지점에서 파손 된 파이프에 대해 EPIPE 오류가 반환됩니다.

+4

@varevarao : 전송 대기열과 특정 간격으로 보내는 것이 해결 방법이라고 생각하지 않습니다. 전송할 MTU 이상이 될 때까지 전송 큐를 대기하는 것은 응용 프로그램이 지연으로 인해 작동 할 수있는 경우 일시적인 해결책이 될 수 있습니다. –

3

아마도 40 바이트가 파이프 버퍼에 들어가고 40000 바이트가 맞지 않을 수 있습니다.

편집

: 닫힌 파이프에 기록 할 때

송신 프로세스가 SIGPIPE 신호를 전송됩니다. 나는 신호가 언제 보내지는지 정확히 알지 못한다. 또는 파이프 버퍼가 이것에 어떤 영향을 미치는지. sigaction 호출로 신호를 트래핑하여 복구 할 수 있습니다.

6

소켓의 현재 상태는 'keep-alive'활동에 의해 결정됩니다. 귀하의 경우에는 send 호출을 발행 할 때 keep-alive 활동은 소켓이 활성 상태임을 나타내므로 send 호출은 필요한 데이터 (40 바이트)를 버퍼에 쓰고 오류를 반환합니다 .

더 큰 청크를 보내면 송신 통화가 차단 상태가됩니다. 소켓 I 비 블록에 배치되지 않는 한 메시지가 소켓의 송신 버퍼에 맞지 않는 경우

, (전송) 일반적으로 블록,/:

는 전송 매뉴얼 페이지이 확인 O 모드. 비 블로킹 모드에서이 경우 EAGAIN을 반환합니다.

무료 사용 가능한 버퍼를 차단하는 동안 발신자에게 (연결 유지 메커니즘으로) 다른 쪽 끝이 더 이상 존재하지 않는다고 통보되면 발신 통화가 실패합니다.

정확한 시나리오를 예측하는 것은 언급 된 정보로는 어렵지만, 저는 이것이 당신 문제의 원인이되어야한다고 생각합니다.

+1

소켓의 현재 상태가 ACK 활동에 의해 관찰됩니다. Keepalive는 단 하나의 작은 소스 ACK 활동이며 기본적으로 해제되어 있습니다. – EJP