2012-01-22 5 views
2

나는 홈 서버에서 실행되는 자바 프로그램을 가지고있다. 또한 서버에 메시지를 보내고 소켓을 사용하여 응답을받는 Java 클라이언트 프로그램이 있습니다.자바 소켓 통신 - 속도 향상

나는 그것을 성공적으로 구현했다. 그러나 조금 느려 보이고 가능한 한 빨리 얻으 려하고있다.

public class Server implements Runnable{ 
    static ServerSocket socket1; 
    protected final static int port = 4701; 
    static Socket connection; 
    static StringBuffer process; 

private String handleRequest(String req){ 
    if(req.equals("marco")){ 
     return "polo"; 
    }else 
     return "null"; 

} 

public void run(){ 
    try { 
     socket1 = new ServerSocket(port); 
     int character; 

     while (true) { 
      connection = socket1.accept(); 

      BufferedInputStream is = new BufferedInputStream(connection.getInputStream()); 
      InputStreamReader isr = new InputStreamReader(is); 
      process = new StringBuffer(); 
      while ((character = isr.read()) != 13) { 
       process.append((char) character); 
      } 
      String returnCode = handleRequest(process.toString()) + (char) 13; 
      BufferedOutputStream os = new BufferedOutputStream(connection.getOutputStream()); 
      OutputStreamWriter osw = new OutputStreamWriter(os, "US-ASCII"); 
      osw.write(returnCode); 
      osw.flush(); 
     } 
    } catch (IOException e) { 
     System.out.println("error starting server " + e.getMessage()); 
    } 
    try { 
     if(connection != null) 
      connection.close(); 

    } catch (IOException e) { 
    } 

클라이언트

String host = "xx.xx.xx.xxx"; 
    int port = 4701; 

    StringBuffer instr = new StringBuffer(); 

    try { 
     InetAddress address = InetAddress.getByName(host); 

     Socket connection = new Socket(address, port); 

     BufferedOutputStream bos = new BufferedOutputStream(connection. 
       getOutputStream()); 

      OutputStreamWriter osw = new OutputStreamWriter(bos, "US-ASCII"); 

      String process = "marco" + (char) 13; 

      osw.write(process); 
      osw.flush(); 

      BufferedInputStream bis = new BufferedInputStream(connection. 
       getInputStream()); 

      InputStreamReader isr = new InputStreamReader(bis, "US-ASCII"); 

      int c; 
      while ((c = isr.read()) != 13) 
       instr.append((char) c); 

      connection.close(); 
      } 
      catch (Exception e){} 

      if(instr.toString().equals("")){ 
       //error 
      } 


} 

그래서 예를 들어, 내가 서버에 다양한 문자열을 보내드립니다 어떻게 서버를 결정하는

서버 : 여기

내 코드입니다 응답합니다. 예를 들어 코드에서 볼 수 있듯이 "marco"를 서버에 보내면 "폴로"가 반환됩니다. 메시지가 끝났음을 프로그램에 알리는 구분 기호로 (char) 13도 있습니다.

누구든지 전송 시간을 단축하는 방법에 대한 아이디어가 있습니까? 나는 독수리의 알고리즘을 비활성화하는 것과 같은 것에 대해 읽었습니다. 그게 도움이 되겠습니까? 아마도 소켓이 순수한 속도를 원한다면 갈 길은 아닙니다. 다른 언어 나 라이브러리가 더 빨라질 수 있습니까?

+0

"조금 느린"이유는 무엇입니까? – Mat

+0

가능한 한 빨리 처리 할 필요가있는 경우가 더 많습니다. –

+3

예, 그게 핵심입니다. 어떻게 그 사실을 알 수 있습니까? – Mat

답변

4

서버 측에서, 당신이 당신의 연결을 닫을 필요를 소켓으로 멀티 스레드 반응을 보여주는 좋은 기사입니다. 그렇지 않으면 미래에 임의의 가비지 수집 시간까지 열려 있습니다.

지연 시간이 거의 필요하다면 DatagramSocket (TCP 대신 UDP)을 사용하십시오. 메시지 전달 보장을 상실하고 손실 된 패킷을 예상해야하지만, 좋은 네트워크의 짧은 메시지의 경우 대기 시간은 휴대 가능한 코드에서 얻을 수있는 것만 큼 좋습니다.

또 다른 옵션은 매번 다시 열지 않고 클라이언트의 소켓 연결을 다시 사용하는 것입니다. 너 같은 작은 메시지의 경우, 대부분의 시간은 아마도 TCP 설정 및 해체에서 소비되고있을 것이다.

미세 최적화는 문자 단위 처리를 중지하고 "marco"및 "polo"를 바이트 문자열로 일치시키는 것입니다. 그러나 눈에 띄는 개선이있을 것 같지 않습니다.

+0

감사합니다. 연결을 유지하는 것에 대해 언급 할 때 이것은 정확히 무엇을 의미합니까? 나는 연결이 열리고 닫힐 때 실제로 진행되고있는 것에 대해 다소 혼란 스럽다고 생각합니다. 열린 연결을 통해 전송되는 일정한 데이터 스트림이 있습니까? "marco"메시지를 보내기 전에 서버와 클라이언트간에 통신이 있습니까? 즉 그들은 서로 먼저 인사를 나눌까요? –

+1

당신의 예에서, 클라이언트는 소켓을 열고, 메시지를 보내고, 응답을 기다리고 연결을 닫습니다. 좀 더 현실적인 시나리오에서는 송수신 논리 주변에 while 루프가있을 수 있습니다. 이 경우 모든 루프 반복에서 열기/닫기 대신 동일한 TCP 연결을 다시 사용하려고합니다. 추가 연결을 만드는시기와시기를 알지 못하는보다 복잡한 시나리오에서 유휴 연결에 만료 된 풀을 사용할 수 있습니다. 이 경우 http://commons.apache.org/pool/을 고려하십시오. –

1

당신이 그것을 빨리하기 위해 다르게 할 수있는 많은 것들이 있지만, 당신이 바꿔야 할 것이 분명합니다. 보통 가장 긴 지연 시간은 네트워크에 있습니다.

루프 오버 또는 대기 시간이 짧은 네트워크에 연결하는 경우 NIO를 사용할 수 있으며 훨씬 빨라질 수 있습니다. 그러나 인터넷 연결을 사용하는 경우 일반 네트워크를 사용하는 경우에는 프로그램의 효율성이 별 차이가 없습니다.

성능을 살펴볼 때 전체 엔드 투 엔드 솔루션을보고 지연이있는 곳을 확인하고 솔루션 속도를 늦추는 가장 큰 요소에 집중해야합니다.

0

소켓이 꽤 낮은 수준이므로 사용하기 쉬운 훨씬 빠른 Java 라이브러리가있을 것입니다. Java는 가장 빠른 언어가 아니며, 가장 많이 사용되는 서버는 대개 C/C++로 작성됩니다. 그러나 Java 서버에서 실행되는 많은 대형 프로젝트가 있습니다 (Tomcat, ResinJBoss).

일반적인 최적화 방법은 서버를 멀티 스레드로 만드는 것입니다. ServerSocket.accept() 다음에는 요청 처리를위한 새 스레드를 작성하므로 서버는 다른 클라이언트를 지원할 수 있습니다. 여기

요청

http://www.oracle.com/technetwork/java/socket-140484.html

+0

답해 주셔서 감사합니다. 실제로 실제로 서비스해야하는 고객의 수는 1 명이지만 재미있는 내용입니다. –