2013-07-14 2 views
1
public static void main(String args[]){ 

    byte[] message = ... 
    Socket socket = ... 
    DataOutputStream dOut = new DataOutputStream(socket.getOutputStream()); 

    dOut.write(message); //#1 

    dOut.close(); 
    socket.close(); 
} 

라인 # 1이 원격 머신으로 플러시하기 위해 대기중인 데이터를 저장한다고 가정 해 봅시다. 그 후 스트림과 소켓이 닫힙니다.자바 TCP 재전송 타임 아웃

우리는 전송 프로세스에서 네트워크에서 알 수없는 문제가 발생한다고 가정하고 운영 체제는 TCP 재전송 제한 시간까지 버퍼에 있던 패킷을 다시 보내 게됩니다.

Java 프로그램에서이 예외를 잡을 수있는 방법이 궁금합니다. 위의 코드는 이미 데이터를 버퍼로 보내고 아마 스트림과 소켓을 닫았을 것이고 (아마도 Java 메인 바디를 종료 할 것이기 때문에) 다른 모든 작업 (TCP 관련, 재전송)을 운영 체제에 남겨 두었습니다.

제 질문은 TCP 재전송 (패킷 손실이 있다고 가정)이 Java 프로그램 종료를 계속할 것입니까? 재전송 타임 아웃 오류를 잡는 가장 좋은 방법은 무엇입니까?

+0

'Java TCP retransmission timeout'또는 실제로 'Java TCP'는 없습니다. * 플랫폼의 * TCP 스택과 그 동작이 있습니다. – EJP

+0

안녕하세요 @EJP, TCP 송신 버퍼가 가득 차면 dOut.write가 차단된다는 것을 알고 있습니다. 버퍼가 꽉 차서 dOut.write가 막히고 네트워크가 데이터 전송에 문제가있어 TCP가 데이터를 계속 전송한다고 가정합시다. 이 경우 TCP가 최대 재전송 시간을 초과 한 후에 dOut.write throw 예외가 발생합니까? 도와 주셔서 감사합니다. – GMsoF

답변

2

TCP는 프로그램 종료 후에도 계속해서 연결을 종료하려고 시도합니다. 일반적으로 응용 프로그램이 종료 자체를 수행하는 것이 좋습니다. 기본적으로 다음 단계를 수행합니다.

  1. Shutdown the TCP connection in the send direction 정상 닫기 시퀀스가 ​​트리거됩니다. 프로토콜이 다른 쪽에서 데이터를 전송하는 것을 금지하는 경우 수신 방향에서도 연결을 종료 할 수 있지만 이렇게하면 상대방이 데이터를 전송할 때 다른 쪽에서 비정상 종료를 감지 할 수 있습니다 보낸 데이터는 손실됩니다.

  2. 다른 쪽 끝이 깨끗하고 비정상적인 종료를 감지 할 때까지 연결을 계속 읽으십시오. 모두 정상적으로 진행되면 상대방이 보낸 데이터를 수신하자마자 정상 종료를 감지하게됩니다.

  3. 핸들을 닫거나 연결에 대한 개체/참조를 삭제하십시오. 실제 TCP 연결은 이미 종료되었습니다.

+0

안녕하세요, 첫 번째 줄을 정확히 이해하지 못합니다. "TCP가 프로그램 종료 후에도 연결을 완전히 종료하려고 시도합니다." 그것은 운영 체제가 이미 종료 된 자바 프로그램조차도 (원격 컴퓨터가 데이터를 수신하거나 타임 아웃 할 때까지) 계속 전송할 것인가? – GMsoF

+0

@GMsoF : 구현에 달려 있습니다. 운영 체제 일 수 있습니다. 운영 체제의 일부가 아닌 별도의 TCP 스택 일 수 있습니다. 그것은 JVM 일 수 있습니다. 그러나 이것이 가장 일반적인 관행입니다. 안전을 위해 응용 프로그램은 원하는 동작을 얻도록 종료를 관리해야합니다. –

+0

JVM이 종료 된 후에는 JVM이 될 수 없습니다. – EJP