2013-08-30 94 views
0

我想在我的程序与其他玩家连接时显示框架。但即使Frame在自己的Thread中运行,它仍然处于冻结状态,而Serversocket正在尝试连接。我怎样才能防止它冻结?即使在其他线程中启动,框架也会冻结

public static boolean connectH(String check, String data, int k){ 
    ServerSocket serverSocket = null; 
    Socket clientSocket = null; 
    PrintWriter out = null; 
    BufferedReader in = null; 
    message = "waiting for someone to connect to your " + check + "-game"; 
    th = new Thread(){ 
     @Override 
     public void run() { 
      c = new Canceler(message); 
     } 
    }; 
    th.start(); 
    try { 
     serverSocket = new ServerSocket(Integer.parseInt(data)); 
    } catch (IOException e) { 
     JOptionPane.showMessageDialog(null, "Could not listen on port: " + data); 
     Main.m.finishgame(-1); 
    } 


    try { 
     clientSocket = serverSocket.accept(); 
    } catch (IOException e) { 
     System.err.println("Accept failed."); 
     System.exit(1); 
    } 

    try { 
     out = new PrintWriter(clientSocket.getOutputStream(), true); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
    try { 
     in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
    try { 
     if (in.readLine().equals(check)){ 
      out.println(k); 
      c.remove(); 
      return true; 
     }else{ 
      out.println(String.valueOf(-1)); 
      c.remove(); 
      return false; 
     } 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
    c.remove(); 
    return false; 
} 
+1

你是如何处理你的线程?在这种情况下,您可能需要使用[SwingWorker](http://docs.oracle.com/javase/7/docs/api/javax/swing/SwingWorker.html)。 – Surveon

+1

'clientSocket = serverSocket.accept();'导致你的'JFrame'冻结,因为它阻塞了'Event Dispatcher Thread'。这部分应该在另一个'Thread'或'SwingWorker'上,如前所述:-) –

+1

你不应该“在不同的线程上运行帧”。所有框架和GUI代码应该在单个线程上运行:AWT-Dispatch线程。您应该将所有其他长时间运行的代码(例如等待接受套接字连接)移至工作线程。 SwingWorker可以使这更容易。 –

回答

1

也许这个例子的Applet会让你开始。

import java.awt.BorderLayout; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.InputStreamReader; 
import java.lang.reflect.InvocationTargetException; 
import java.net.ServerSocket; 
import java.net.Socket; 

import javax.swing.JApplet; 
import javax.swing.JButton; 
import javax.swing.JTextArea; 
import javax.swing.SwingUtilities; 

public class Example extends JApplet 
{ 
    private JButton _jButtonStartGameServer; 
    private boolean _isStarted = false; 
    private GameServer _gameServer = null; 
    private JTextArea _jTextArea; 
    private Thread _gameServerThread = null; 
    private boolean _initialized = false; 

    public Example() 
    { 
     System.out.println("ctor..."); 
    } 

    private void initComponents() 
    { 
     if (_initialized) 
     { 
      return; 
     } 

     _jButtonStartGameServer = new JButton("Start Game Server"); 
     _jButtonStartGameServer.addActionListener(new ActionListener() 
     { 
      public void actionPerformed(ActionEvent e) 
      { 
       if (!_isStarted) 
       { 
        startupGameServer(); 
       } 
       else 
       { 
        shutdownGameServer(); 
       } 
      } 
     }); 
     setLayout(new BorderLayout(0, 0)); 

     _jTextArea = new JTextArea(); 
     add(_jTextArea); 
     add(_jButtonStartGameServer, BorderLayout.NORTH); 

     _initialized = true; 
    } 

    public void init() 
    { 
     System.out.println("init... " + Thread.currentThread()); 
     try 
     { 
      SwingUtilities.invokeAndWait(new Runnable() 
      { 
       public void run() 
       { 
        initComponents(); 
       } 
      }); 
     } 
     catch (InvocationTargetException e) 
     { 
      e.printStackTrace(); 
     } 
     catch (InterruptedException e) 
     { 
      e.printStackTrace(); 
      Thread.currentThread().interrupt(); 
     } 
    } 

    public void start() 
    { 
     System.out.println("start... " + Thread.currentThread()); 
     SwingUtilities.invokeLater(new Runnable() 
     { 
      public void run() 
      { 
       setSize(640/2, 480/2); 
      } 
     }); 
    } 

    public void stop() 
    { 
     System.out.println("stop... " + Thread.currentThread()); 
     shutdownGameServer(); 
    } 

    public void destroy() 
    { 
     System.out.println("destroy " + Thread.currentThread()); 
     shutdownGameServer(); 
    } 

    void displayException(Throwable t) 
    { 
     log("Got exception: " + t); 
    } 


    void processMessageFromOtherPlayer(String msg) 
    { 
     log("Received message from other player: " + msg); 
    } 

    void gameServerThreadExiting() 
    { 
     shutdownGameServer(); 
    } 

    public void startupGameServer() 
    { 
     _gameServer = new GameServer(); 
     _gameServerThread = new Thread(_gameServer); 
     _gameServerThread.start(); 
     _isStarted = true; 
     _jButtonStartGameServer.setText("Stop Game Server"); 
    } 

    public void shutdownGameServer() 
    { 
     GameServer gs = _gameServer; 
     if (gs != null) 
     { 
      gs.cancel(); 
     } 
     Thread t = _gameServerThread; 
     try 
     { 
      if (t != null) 
      { 
       t.join(); 
      } 
     } 
     catch (InterruptedException ie) 
     { 
      Thread.currentThread().interrupt(); 
     } 
     _gameServer = null; 
     _jButtonStartGameServer.setText("Start Game Server"); 
     _isStarted = false; 
    } 

    void log(final String msg) 
    { 
     System.out.println("Log (" + Thread.currentThread() + "): " + msg); 
     Runnable r = new Runnable() 
     { 
      public void run() 
      { 
       StringBuilder sb = new StringBuilder(_jTextArea.getText()); 
       sb.append(msg); 
       sb.append("\n"); 
       _jTextArea.setText(sb.toString()); 
      } 
     }; 
     if (SwingUtilities.isEventDispatchThread()) 
     { 
      r.run(); 
     } 
     else 
     { 
      SwingUtilities.invokeLater(r); 
     } 
    } 

    class GameServer implements Runnable 
    { 
     volatile ServerSocket _ss = null; 
     volatile Socket _s = null; 
     volatile InputStream _sis = null; 
     volatile boolean _cancel = false; 

     public void run() 
     { 
      try 
      { 
       _ss = new ServerSocket(9999); 
       log("Waiting for other player, listening on port: " + _ss.getLocalPort()); 
       _s = _ss.accept(); 
       log("Connection accepted from: " + _s.getRemoteSocketAddress()); 
       _sis = _s.getInputStream(); 
       BufferedReader br = new BufferedReader(new InputStreamReader(_sis, "UTF-8")); 
       while (true) 
       { 
        if (_cancel) 
        { 
         break; 
        } 
        final String msg = br.readLine(); 
        if (msg == null) 
        { 
         // connection closed/lost 
         break; 
        } 
        SwingUtilities.invokeLater(new Runnable() 
        { 
         public void run() 
         { 
          processMessageFromOtherPlayer(msg); 
         } 
        }); 
       } 
      } 
      catch (final Throwable t) 
      { 
       // don't show the user the exception if the user is canceling 
       if (!_cancel) 
       { 
        SwingUtilities.invokeLater(new Runnable() 
        { 
         public void run() 
         { 
          displayException(t); 
         } 
        }); 
       } 
       else 
       { 
        // even if the user is canceling, we might be interested in the exception, though 
        t.printStackTrace(); 
       } 
      } 
      log("Game server thread exiting..."); 
      SwingUtilities.invokeLater(new Runnable() 
      { 
       public void run() 
       { 
        gameServerThreadExiting(); 
       } 

      }); 
     } 

     public void cancel() 
     { 
      _cancel = true; 

      ServerSocket ss = _ss; 
      if (ss != null) 
      { 
       try 
       { 
        ss.close(); 
       } 
       catch (IOException e) 
       { 
        e.printStackTrace(); 
       } 
      } 

      Socket s = _s; 
      if (s != null) 
      { 
       try 
       { 
        s.close(); 
       } 
       catch (IOException e) 
       { 
        e.printStackTrace(); 
       } 
      } 

      InputStream sis = _sis; 
      if (sis != null) 
      { 
       try 
       { 
        sis.close(); 
       } 
       catch (IOException e) 
       { 
        e.printStackTrace(); 
       } 
      } 
     } 
    } 
} 
+0

您的代码应该解决冻结问题,但另一个问题是,我仍然需要等到服务器连接后才能继续进行其他计算。我应该怎么做? 另一件事是我必须返回一个值。 –

+0

服务器连接在代码行'log(“接受的连接:”+ _s.getRemoteSocketAddress());',所以你可以在那里放置更多的代码。我不明白你的意思是什么:返回一个值。这有点模棱两可。 –

+0

我想让程序继续之前的位置。例如: ... 如果(mode == SERVER){ info = //启动服务器并发送info2 /接收信息 否则如果(mode == CLIENT){ info2 = //连接到服务器并发送信息/ receive info2 } infototal = info + info2 ... “我不明白你的意思是什么:返回一个值,这有些含糊。” 服务器端和客户端都发送和接收一些需要进行以下计算的数据,因此我必须返回这些信息。 –

相关问题