2011-09-07 66 views
2

我有一小段代碼運行在包含SWING控件的小程序中,並用於將信息寫入某個端口上的套接字,然後偵聽響應。這工作正常,但它有一個問題。端口偵聽器基本上處於循環狀態,直到服務器接收到空值。我希望用戶能夠在小應用程序實例化的GUI中執行其他操作,同時等待服務器響應(這可能需要幾分鐘時間)。我也需要擔心服務器和客戶端斷開連接。但是,代碼被寫入的方式,applet似乎凍結(它真的在一個循環中),直到服務器響應。我該如何讓聽衆在後臺進行聆聽,以便在節目中發生其他事情。我假設我需要使用線程,並且我確信這個應用程序很容易實現,但是我缺乏堅實的線程基礎阻礙了我。下面是代碼(你可以看到它有多簡單)。我怎樣才能提高它,使其做什麼,我需要做的>需要幫助改進一個java客戶端端口監聽器

public String writePacket(String packet) { 
/* This method writes the packet to the port - established earlier */ 
    System.out.println("writing out this packet->"+packet+"<-"); 
    out.println(packet); 
    String thePacket = readPacket(); //where the port listener is invoked. 
    return thePacket; 
    } 
    private String readPacket() { 
     String thePacket =""; 
     String fromServer=""; 
     //Below is the loop that freezes everything. 
    try { 
     while ((fromServer = in.readLine()) != null) { 
     if (thePacket.equals("")) thePacket = fromServer; 
     else 
     thePacket = thePacket+newLine+fromServer; 
    } 
     return thePacket; //when this happens, all listening should stop. 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 
    e.printStackTrace(); 
    return null; 
    } 

    } 

感謝,

埃利奧特

+0

Java併發在實踐中很好看的,以加強你的線程基礎;除了你是對的;一個用於套接字連接的線程池。 – Scorpion

回答

2

有很多不同的方法讓IO在不同的線程上執行,但在這種情況下,您可能想要使用SwingWorker

您的代碼看起來是這樣的:

private final Executor executor = Executors.newSingleThreadExecutor(); 

public void writePacket(final String packet) 
{ 
    // schedules execution on the single thread of the executor (so only one background operation can happen at once) 
    // 
    executor.execute(new SwingWorker<String, Void>() 
     { 

     @Override 
     protected String doInBackground() throws Exception 
     { 
      // called on a background thread 


      /* This method writes the packet to the port - established earlier */ 
      System.out.println("writing out this packet->"+packet+"<-"); 
      System.out.println(packet); 
      String thePacket = readPacket(); //where the port listener is invoked. 
      return thePacket;    
     } 

     @Override 
     protected void done() 
     { 
      // called on the Swing event dispatch thread 


      try 
      { 
      final String thePacket = get(); 

      // update GUI with 'thePacket' 
      } 
      catch (final InterruptedException e) 
      { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
      } 
      catch (final ExecutionException e) 
      { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
      } 
     } 
     }); 
} 

private String readPacket() 
{ 
    String thePacket =""; 
    String fromServer=""; 
    //Below is the loop that freezes everything. 
    try 
    { 
    while ((fromServer = in.readLine()) != null) 
    { 
     if (thePacket.equals("")) 
     thePacket = fromServer; 
     else 
     thePacket = thePacket+newLine+fromServer; 
    } 
    return thePacket; //when this happens, all listening should stop. 
    } 
    catch (IOException e) 
    { 
    e.printStackTrace(); 
    return null; 
    } 
} 
0

所有網絡I/O應該是在一個單獨的線程。

BTW readLine()在服務器關閉連接時返回null,而不是當它完成發送數據的時刻。