2016-08-21 69 views
2

我目前正在製作一個允許兩個玩家通過套接字的桌面遊戲。我也試圖添加一個遊戲聊天,但無法無天,我需要一種方法讓Frame類正常工作(Jbuttons,將文本輸入到jscroll區域等),但也會發送傳入對象。我認爲實施可運行性是最好的選擇。 這裏是我的run方法:套接字多線程問題

public void run() { 
    while(running){ 
     Object obj = null; 
     try { 
      obj = connection.receiveObjects(); 
     } catch (ClassNotFoundException) { 
      e.printStackTrace(); 
     } catch (IOException e){ 
      e.printStackTrace(); 
      running = false; 
     if(obj != null){ 
      if(obj instanceof String){ 
       showMessage((String)obj); 
      } 
     } 
    } 

} 

我的連接類只是一個服務器或客戶端,並使用這些方法:

public void sendObjects(Object obj) throws IOException{ 
     output.writeObject(obj); 
     output.flush(); 

} 
public Object receiveObjects() throws IOException, ClassNotFoundException{ 
     return input.readObject(); 
} 

在框架類的構造函數我叫

Thread thread = new Thread(this); 
thread.start(); 

希望run方法不會干擾actionPerformed方法。但令我沮喪的是,當我點擊一個jbutton(它只是調用send()方法)時,程序凍結,並且沒有任何內容被髮送。

下面是其他必要的代碼:

private JTextArea textBox; 
private JScrollPane pane; 
private JTextArea userText; 
private JScrollPane userPane; 



private void send(){ 
    String message = "YOU- " + userText.getText(); 
    userText.setText(""); 
    String totalMessage = textBox.getText(); 
    textBox.setText(totalMessage + "/n" + message); 
    try { 
     connection.sendObjects(message); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
} 

public void showMessage(String s){ 
    String totalMessage = "Opponent- " + textBox.getText(); 
    textBox.setText(totalMessage + "/n" + s); 
} 

我的希望是,一旦我得到了聊天的工作,我還可以添加在發送的零碎和調用其他方法則做的一切,我需要(的instanceof)。我可能會創建一個單獨的類來實現runnable來處理數據傳輸,但我希望我可以在一個類中完成所有操作,並且不明白爲什麼我不能。我確實花費了至少一個半小時來查看多線程,但我無法解決問題。我很抱歉如果我正在查看任何明顯的內容,但是mutithreading和套接字遠遠超出了我的舒適區和AP Comp sci課程教育範圍。

+0

您應該單獨捕獲'EOFException'並終止th當你捕捉到它時讀取循環。除「SocketTimeoutException」之外的所有其他'IOExceptiions'對連接都是致命的;應該被記錄;並且還應該終止讀取循環。 – EJP

+0

EOFException?我不認爲我有這些,但我會編輯IOException的讀循環。 – Deek3117

+0

當對方關閉連接時,您將獲得'其中之一'。 – EJP

回答

0

除了UI線程,你需要:

  1. 一個線程不斷偵聽傳入的數據
  2. 一個線程發送數據

您有#1,但並不#2,所以修改send()方法如下:

private void send() { 
    // Do the UI tasks on the UI thread 
    final String message = "YOU- " + userText.getText(); 
    userText.setText(""); 
    String totalMessage = textBox.getText(); 
    textBox.setText(totalMessage + "\n" + message); 
    // Start new thread to do the networking (send data) 
    new Thread(new Runnable() { 
     @Override 
     public void run() { 
      try { 
       connection.sendObjects(message); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
     } 
    }).start(); 
} 
+0

哇,3個線程?我永遠不會想到!謝謝!它不再凍結,但似乎從未接收到該消息?我把一個System.out.print放在read循環中,它只打印一次,表明這個消息永遠不會發送通過 – Deek3117

+0

今天上午經過一些測試後,看起來connection.sendObjects(消息)永遠不會被調用,或者凍結。我在它之前和之後放了S.O.P,只有之前打印過...... – Deek3117