2009-07-30 5 views
0

자바 소켓에서 루프를 읽는 중입니다.Java 소켓을 다시 여는 방법

읽기가 예외를 throw하면 소켓을 다시 열려고합니다.

이를 테스트하기 위해 간단히 소켓을 닫고 예외를 잡습니다. 예외를 throw

serverSocket = new ServerSocket(port) 
socket = serverSocket.accept() 

: 테스트를위한 즉각적인 문제입니다

java.net.BindException: The socket name is already in use 

내가 소켓을 다시 열려고하면

캐치이다. 그러나 생산에서도 발생할 수 있습니다.

예외가 발생한 후 어떻게 새 소켓 연결을 열어 안정적으로 복구 할 수 있습니까?

+1

스레드가 예외를 throw하면 serversocket을 닫은 다음 (10) 동일한 포트를 다시 열려면 10 초 동안 기다려야합니다. – akarnokd

+0

어떤 이유로 서버가 소켓을 닫고 클라이언트가 isClosed()를 감지하면 서버를 다시 열 수는 없지만 클라이언트는 새 소켓을 만들어야합니다. 10 초는 임의로 보입니다. 지수 백 오프 재시도 패턴이 더 적절할 것입니다. –

답변

0

회의 세션 중에 예외가 발생하면 소켓을 닫아야합니다.

5

내가하는 말을 오해하면 유감입니다.

소켓에서 read() 메소드가 실패하면 ServerSocket을 닫지 않습니다.

새 것을 만들지 않고도 serverSocket.accept()를 호출 할 수 있어야합니다. BindException을 얻는 이유가 여기 있다고 생각합니다.

4

필요한 것은 ServerSocket을 한 번 만들고 허용 된 소켓을 핸들러에 전달하는 것입니다. 일반적으로 다른 스레드에서 처리됩니다.

오류는 동일한 포트에서 두 번 청취하려고 시도하는 것이므로 불가능합니다.

article이 도움이 될 수 있습니다. 다음 코드 샘플 중 하나입니다

  1. 없음 지연 후 필요하지 않은

새로운 ServerSocket를 만들기 ServerSocket의

  • 를 닫습니다 : 나는 일에 무엇을 발견

    public void await() { 
        ServerSocket serverSocket = null; 
        int port = 8080; 
        try { 
         serverSocket = new ServerSocket(port, 1, 
         InetAddress.getByName("127.0.0.1")); 
        } 
        catch (IOException e) { 
         e.printStackTrace(); 
         System.exit(1); 
        } 
    
        // Loop waiting for a request 
        while (!shutdown) { 
         Socket socket = null; 
         InputStream input = null; 
         OutputStream output = null; 
         try { 
          socket = serverSocket.accept(); 
          input = socket.getInputStream(); 
          output = socket.getOutputStream(); 
    
          // create Request object and parse 
          Request request = new Request(input); 
          request.parse(); 
    
          // create Response object 
          Response response = new Response(output); 
          response.setRequest(request); 
          response.sendStaticResource(); 
    
          // Close the socket 
          socket.close(); 
    
          //check if the previous URI is a shutdown command 
          shutdown = request.getUri().equals(SHUTDOWN_COMMAND); 
         } 
         catch (Exception e) { 
          e.printStackTrace(); 
          continue; 
         } 
        } 
    } 
    
  • 2

    이이었다 ServerSocket를 닫습니다. 이것은 IBM AIX 머신에 있습니다. 아마도 다른 플랫폼에서는 동작이 다릅니다.

    소켓을 닫을 필요가 없습니다.

    Socket에 연결 종료의 다른 쪽에서 복구하기위한 시간 초과를 추가했습니다. 시작시 및 예외적으로 실행되는 코드는 다음과 같습니다.

    if (serverSocket != null) serverSocket.close(); 
    serverSocket = new ServerSocket(port); 
    socket = serverSocket.accept(); 
    socket.setSoTimeout(TIMEOUT); 
    is = socket.getInputStream(); 
    

    팁을 사용하여 ServerSocket을 닫으면 감사합니다. 저것은 맞은 궤도에 저를 얻었다. 또한 유용한 네트워크 프로그래밍 참조를 위해.

    +0

    혼란 스럽군요 ... 왜 클라이언트 소켓 대신 ServerSocket을 닫아야합니까? 클라이언트 측에서 재 연결을 시작해야하며, ServerSocket을 닫았다가 다시 열지 않아도됩니다. 많은 양의 데이터를 업로드하고 다시 시작해야하는 경우 "새로운"연결을 수락하면 서버가 세션 ID를 클라이언트에 전송하게해야합니다. 연결이 끊어진 후에 서버는 세션의 현재 상태를 저장해야하며 클라이언트가 다시 연결하려고하면 "다시 시작"연결을 열 때 이전 세션 ID를 전송합니다. – rob

    관련 문제