2016-08-21 68 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