리눅스 SIGPIPE 신호

王林
풀어 주다: 2024-02-19 16:00:33
앞으로
419명이 탐색했습니다.

TCP 통신 당사자에서는 설명의 편의를 위해 아래에서 통신 당사자를 A, B로 대체합니다.

TCP 프로토콜에 따르면 A가 연결을 끊은 후에도 B가 계속 데이터를 보내면 B는 A의 RST 응답을 받게 됩니다. B가 계속해서 데이터를 보내면 시스템은 SIGPIPE 신호를 보내 연결이 끊어졌음을 알리고 전송을 중단합니다.

SIGPIPE 신호에 대한 시스템의 기본 처리 동작은 프로세스 B가 종료되도록 하는 것입니다.

SIGPIPE 신호에 대한 운영 체제의 기본 처리 동작은 매우 비우호적입니다. 분석해 보겠습니다.

Linux SIGPIPE信号

TCP 통신은 두 개의 단방향 채널에 해당하는 전이중 채널이며 연결의 각 끝이 하나를 담당합니다.

피어가 "닫힐" 때 의도는 두 채널 전체를 닫는 것이지만 로컬 끝은 FIN 패킷만 수신합니다.

TCP 프로토콜 규정에 따라 한쪽 끝이 자신이 담당하는 단방향 채널을 닫으면 여전히 데이터를 받을 수 있지만 더 이상 데이터를 보낼 수 없습니다.

즉, TCP 프로토콜의 한계로 인해 통신 당사자는 상대방의 소켓이 close 또는 shutdown을 호출했는지 알 수 없습니다.

으아악

종료 기능의 매개변수 "방법"은 SHUT_RD, SHUT_WR 또는 SHUT_RDWR을 닫도록 설정할 수 있습니다. 이는 수신 및 송신 채널을 개별적으로 닫거나 송신 및 수신 채널을 동시에 닫는 것을 나타내는 데 사용됩니다.

FIN 패킷을 수신한 소켓에서 read/recv 메서드를 호출합니다. 수신 버퍼가 비어 있으면 0이 반환됩니다. 이는 종종 연결이 닫혔다는 것을 나타냅니다. 그러나 처음으로 쓰기/보내기 메소드를 호출할 때 송신 버퍼에 문제가 없으면 올바른 쓰기가 반환됩니다(즉, 쓰기/보내기 함수의 반환 값이 0보다 큽니다). 하지만 전송된 메시지로 인해 피어는 RST 메시지로 응답하게 됩니다. 지난번에 프로그램이 쓰기/보내기를 호출했을 때는 정상이었기 때문에 쓰기/보내기 기능을 다시 호출하려고 하면 SIGPIPE 신호가 생성되어 프로세스가 종료되었습니다.

이 기본 동작은 특히 동시에 많은 클라이언트에 서비스를 제공해야 하는 백엔드 서비스용 프로그램을 개발하기 위한 것입니다. 연결에 문제가 있기 때문에 전체 프로세스가 종료될 수 없으며 계속해서 다른 클라이언트에 서비스를 제공할 수 없습니다. 특정 클라이언트.

이 현상을 방지하기 위해 SIGPIPE 신호를 캡처하여 처리하거나 신호를 무시하는 코드는 다음과 같습니다.

으아악

이렇게 설정한 후 write/send 메소드가 두 번째 호출되면 -1이 반환되고 errno 오류 코드가 SIGPIPE로 설정되므로 프로그램은 피어가 닫혔음을 알 수 있습니다.

위 내용은 리눅스 SIGPIPE 신호의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:mryunwei.com
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿