현재 클라이언트가 충돌 한 경우 감지 방법은 통신을 수신 할 때 예외가 발생하는 경우입니다. 나는 이것이 클라이언트가 충돌하면 OS가 소켓을 닫을 것이기 때문이라고 생각한다. 클라이언트 인터넷이 끊어 지거나 PC를 종료 한 경우 예외가 계속 발생합니까? 이런 경우 단절을 처리하는 가장 좋은 방법은 무엇입니까? 감사.TCP 발견 중 드롭 아웃?
답변
소켓 시간 초과는 상당히 길며 OS/구현 의존입니다. 정기적 인 간격으로 클라이언트에 ping을 보내어 사용중인 통신 유형에 따라 클라이언트가 응답 할 수있는 모든 유형의 쿼리를 확인하는 것과 같이 활성화해야합니다.
일반적으로 방법은 당신이 cia TCP/UDP 연결을 수행하는 모든 작업에 대한 시간 초과를 지정합니다. 따라서 응답 (메시지 또는 ACK)이 클라이언트로부터 수신되면 언젠가 소켓은 SocketTimeoutException을 던질 것이다. 예
1)를 Socket.connect 판독에 시간 제한을 설정하기위한 (otherAddress, 초과)
2) socket.setSoTimeout (초과) 용
() 동작.
TCP는 연결을 통해 데이터가 양방향으로 이동하지 않는 경우에도 연결을 무기한 유지하도록 설계되었습니다. 즉, 연결이 닫히지 않고 클라이언트의 네트워크 나 중간 네트워크가 다운되면 예외가 표시되지 않습니다. 실제로 이러한 네트워크가 다운 된 경우 나중에 다시 오면 몇 시간 후에 TCP 그 기간 동안 사용되지 않은 연결은 기본적으로 여전히 거기에 있으며 이후의 통신에 사용할 수 있습니다. 클라이언트 컴퓨터가 충돌하거나 갑자기 꺼지는 경우에도 예외가 발생하지 않습니다. 운영 체제에 따라 종료 프로세스에 모든 연결을 닫는 작업이 포함될 수 있으므로 클라이언트 컴퓨터가 정상적으로 종료되면 예외가 발생할 수 있습니다.
네트워크가 특정 기간 동안 유실되거나 클라이언트가 충돌 할 때 연결을 끊으려면 일반적으로 TCP 연결 유지를 설정하는 것이 가장 좋습니다. Java에서는 Socket.setKeepalive (true)를 호출하여 TCP Keepalive를 활성화 할 수 있습니다. 이렇게하면 연결의 다른 쪽 끝이 아직 활성 상태인지 확인하기 위해 소켓에서 가끔 프로브 패킷을 보내 게됩니다.
TCP keepalive 검사 간의 기본 간격은 일반적으로 2 시간이며 일반적으로 시스템 전체 속성입니다. 간격을 줄이려면 시스템 구성을 변경해야합니다.
클라이언트를 Ping하고 잠시 응답을 기다립니다. 없으면 클라이언트 연결이 끊어졌습니다. – svz
더 이상 존재하지 않는 소켓에서 read()를 시도하면 a) 거의 즉시 연결 감지 또는 b) 시간 초과가 발생합니다. 어느 쪽이든 그것은 IOException을 던질 것이다. –
@PeterLawrey 그러나 기본 읽기 제한 시간은 무한합니다. 당신은 그것을 설정해야하며, 가치를 선택하는 것은 재미있을 수 있습니다. – EJP