2010-03-24 3 views
2

데이터를 읽는 TCP 소켓이 있습니다. 데이터를 읽을 때 오류가 발생하면 undef (NULL) 값을 반환합니다. 잘못된 형식의 메시지 나 깨진 소켓 때문에 오류가 발생할 수 있습니다. 누군가 소켓의 상태를 반환하는 특정 함수가 있는지 말해 줄 수 있습니까?Perl에서 어떻게 TCP 소켓 상태를 테스트 할 수 있습니까?

+0

상태 란 무엇을 의미합니까? 열렸는지 닫혔는지? –

+0

소켓이 유효한 상태인지 여부, 즉 tcp 연결이 활성화되어 있는지 여부 –

답변

4

doh!, 답은 회고 적이었고, 연결된 통화를 사용했습니다.

$socket = IO::Socket::INET(localhost, 1000); 
die "no connection" unless $socket -> connected(); 
$socket -> send("your face here for $20"); 
die "socket is dead" unless $socket -> connected(); 
$socket -> recv($data); 
+2

이것은 아마도 원하는 것이 아닙니다. 이 모든 호출은 초기 연결이 성공했는지 또는 사용자 자신의 프로그램이나 피어에 의해 연결이 정상적으로 종료되었는지 여부를 알려줍니다. 피어 컴퓨터 충돌과 같은 다른 연결 문제가 있거나 피어 응용 프로그램이 잠겨 있거나 피어 컴퓨터를 네트워크 문제로 인해 사용할 수없는 경우이 방법이 도움이되지 않습니다. 기본적으로, 이것은 잡으려고하는 오류 조건을 포착하지 않습니다. –

+0

사실,하지만 유스 케이스에서는 메시지 디코딩 프로세스가 실패했다는 것을 알고 있습니다. 잘못된 형식의 메시지와 깨진 소켓을 구별하는 방법이 필요했습니다. –

+0

또한 btw, 연결된 함수는 select 함수와 함께 사용하는 것이 가장 좋습니다. –

6

소켓이 열렸는지 닫혔는지를 감지하는 방법은 세 가지가 있지만 둘 다 100 % 완전 보장이 아닙니다. 소켓이 순서대로 종료 겪었습니다

my $ret = recv($sockfd, $buff, 1, MSG_PEEK | MSG_NOWAIT); 

경우 shutdown for writing or called closeFIN 패킷이 다음이 호출이 0 길이됩니다 도착했다라고 피어 즉, 나타내는 읽기 :

첫 번째는 to attempt a read on the socket as follows입니다 닫힌 소켓. 이것은 OS가 연결을 닫고 FIN을 전송하기 때문에 피어 응용 프로그램이 충돌 한 경우에도 도움이됩니다. 그러나 피어 컴퓨터가 손상되었거나 피어 응용 프로그램이 잠긴 경우 각 연결 종료가 독립적 상태를 유지하므로 도움이되지 않습니다.

끊어진 연결을 감지하는 두 번째 방법은 피어를 조사하는 것입니다. 0 길이의 패킷을 피어 (처리 할 수 ​​있어야 함)에 보내고 응용 프로그램이 손상된 경우 두 번째 0 길이의 패킷을 보내면 응용 프로그램에 SIG_PIPE 신호 indicating a broken pipe이 전송됩니다.

이 문제를 해결하는 또 다른 방법은 응용 프로그램 수준의 하트 비트를 사용하는 것입니다.이 하트 비트에서 동료는 주기적으로 하트 비트 패킷을 서로에게 보내어 그것이 살아 있고 올바르게 작동하고 있음을 나타냅니다.

마지막 옵션은 SO_KEEPALIVE 소켓 옵션을 사용하는 것입니다. 약 2 시간 동안 사용하지 않으면 깨진 소켓 만 감지하므로 제한적으로 사용합니다.

연결이 끊어 졌을 때 상당히 빨리 알아야하는 경우 가장 안정적인 옵션은 응용 프로그램 수준의 하트 비트가 될 것입니다.

+0

실제로는 'MSG_DONTWAIT' 플래그 이름 – AlexM

관련 문제