2011-10-17 5 views
2

하나의 서버가 항상 같은 포트 (서버 및 서버)를 사용하여 한 클라이언트에서 연결을 허용하는 시나리오를 테스트하려고합니다. 클라이언트 쪽).항상 동일한 포트를 사용하는 여러 비동기 Java 클라이언트 - 서버 연결

목적은 1 개의 클라이언트 응용 프로그램이 100/분보다 큰 비율로 작은 데이터를 보내는 것입니다. 분명한 해결책은 클라이언트와 서버 사이에 항상 연결된 링크를 만드는 것이지만, 이는 생산 단계이며 이미 구현 된 코드에서 더 큰 변경이 필요할 것입니다. 오늘 구현 한 솔루션을 통해 우리는 항상 TIME_WAIT에 + -1K의 연결을 보유하고 있으며이를 제거하려고합니다.

나는 간단한 테스터를 구현하고, 코드는 다음과 같습니다

public class Server { 
    public static void main(String[] args) { 
     ServerSocket ssock = null; 
     try { 
      ssock = new ServerSocket(); 
      ssock.bind(new InetSocketAddress(Common.SERVER_PORT)); 
     } catch (IOException e) { 
      e.printStackTrace(); 
      System.exit(-1); 
     } 

     while(true){ 
      try{ 
       Socket cSock = ssock.accept(); 

       BufferedReader reader = new BufferedReader(new InputStreamReader(cSock.getInputStream())); 
       reader.readLine(); 

       PrintWriter writer = new PrintWriter(cSock.getOutputStream()); 
       writer.println(Common.SERVER_SEND); 
       writer.flush(); 

       reader.close(); 
       writer.close(); 
       cSock.close(); 

      }catch (Exception e) { 
       System.out.println(e.getClass().getName() + ": " + e.getMessage()); 
      } 
     } 
    } 
} 


public class Client { 

    public static void main(String[] args) throws Exception { 
     InetSocketAddress cliAddr = new InetSocketAddress(
       InetAddress.getByName(args[0]), 
       Common.CLIENT_PORT); 

     InetSocketAddress srvAddr = new InetSocketAddress(
       InetAddress.getByName(args[1]), 
       Common.SERVER_PORT); 

     for(int j=1;j<=50;j++){ 
      Socket sock = null; 
      try{ 
       sock = new Socket(); 
       sock.setReuseAddress(true); 
       sock.bind(cliAddr); 
       sock.connect(srvAddr); 

       PrintWriter writer = 
         new PrintWriter(
           sock.getOutputStream()); 

       writer.println(Common.CLIENT_SEND); 
       writer.flush(); 

       BufferedReader reader = 
         new BufferedReader(
           new InputStreamReader(
             sock.getInputStream())); 
       reader.readLine(); 

      }catch (Exception e) { 
       System.out.println(e.getClass().getName() + ": " + e.getMessage()); 
       System.exit(-1); 
      }finally{ 
       if(sock!=null) sock.close(); 
       System.out.println("Done " + j); 
      } 
     } 
    } 
} 

public class Common { 
    public static final int SERVER_PORT = 9009; 
    public static final int CLIENT_PORT = 9010; 
    public static final String CLIENT_SEND = "Message"; 
    public static final String SERVER_SEND = "OK"; 
} 

난 항상

java.net.ConnectException: Connection timed out 

를 얻을 하나 개의 클라이언트 실행에서, 윈도우 호스트에서 클라이언트와 서버를 실행할 때 리눅스 호스트에서 클라이언트와 서버를 실행할 때, 일부 클라이언트 실행시 나는

java.net.NoRouteToHostException: Cannot assign requested address 

나는이 행동에 대해 머리를 쓰러 뜨렸다. 누군가 내가 원하는 것을 할 수 있는지, 그리고 내가 뭘 잘못하고 있는지 말해 줄 수 있습니까?

+1

많은 연결이 있고 큰 코드 블록으로 속도를 높이고 싶지 않으며 작동하지 않습니다. 아니면 귀하의 클라이언트 코드가 서버를 찾을 수 없다는 사실에 대한 귀하의 질문입니까? 후자라면 분명히 질문을 수정해야합니다. – bdares

+0

난 단지 이미 구현 된 큰 코드 블록을 개선하고 싶습니다 ... 위의 코드는 단지 테스트 응용 프로그램입니다! – aflopes

+0

클라이언트는 서버와의 일부 메시지를 찾아 연결하고 교환하지만 시계처럼 작동하지 않습니다. 내 생각 엔 2 개의 응용 프로그램이 양쪽 끝의 연결 종료를 제어 할 수 없기 때문에 모든 것이 섞여서 발생합니다. – aflopes

답변

0

TIME_WAIT 상태를 제거하려면 닫기를 수신하는 피어가되지 마십시오. 닫기를 시작하는 동료가 되십시오. 이 경우 응답을 읽은 직후 연결을 닫고 응답을 보낸 직후에 연결을 종료하는 대신 EOF를 읽도록 다른 요청을 찾도록 서버를 순환 시키십시오. 그러나 모든 TIME_WAIT 상태는 클라이언트가 아닌 서버에 누적되므로 문제가 심각해집니다. 다른 한편, 서버는 이제 연결 당 여러 개의 요청을 수용 할 수 있도록 구성되어 있으므로 연결 풀을 사용하도록 클라이언트를 조정하면 모든 문제가 해결됩니다.

+0

TIME_WAIT 연결을 서버쪽에 전달하는 것은 옵션이 아닙니다. 그것은 나에게 클라이언트와 서버에서 더 큰 변화를 만들어야 할 것 같다. – aflopes

+0

나는 옵션에 동의하지 않는다. 실제로 나는 그렇게 말했지만, 내가 말한 나머지는 어떨까? 왜 단일 클라이언트 포트를 사용하고 있습니까? 여기서 질문 한 내용에 언제 대답 할 예정입니까? – EJP