在Java中搜索无限循环的替代方案

时间:2014-10-21 18:11:34

标签: java sockets loops

我正在做我的家庭作业,这是关于聊天程序。它有两个接口,一个用于服务器,第二个用于客户端。程序流程如下:

  1. 服务器在某个端口上启动连接
  2. 客户端启动并尝试连接到服务器
  3. 如果一切正常,他们就会开始聊天
  4. 其中一个终端类型" TERMINATE"谈话将结束。
  5. 此程序源自 Deitel& Deitel Java How To Program 6e 一书。该示例每个接口只有两个元素:用于显示消息的displayArea(JTextArea)和用于输入消息的输入(JTextField)。

    Enter 会将消息发送给其他人。

    下面是Server.java的一段代码。它在无限循环中做了一些重复的动作。

    public void runServer() {
        // set up server to receive connections; process connections
        SwingUtilities.invokeLater(new Runnable() {
    
            public void run() 
            {
                try {
    
                    // Step 1: Create a ServerSocket.
                    String portNum = txtPort.getText();
                    server = new ServerSocket(Integer.parseInt(portNum), 100);
    
                    InetAddress ip = InetAddress.getLocalHost();
                    txtServerIP.setText(ip.getHostAddress());
    
                    while (true) {
    
                        try {
                            waitForConnection(); // Step 2: Wait for a connection.
                            getStreams(); // Step 3: Get input & output streams.
                            processConnection(); // Step 4: Process connection.
                        }
                        // process EOFException when client closes connection
                        catch (EOFException eofException) {
                            System.err.println("Client terminated the connection.");
                        }
                        finally {
                            closeConnection(); // Step 5: Close connection.
                            ++counter;
                        }
                    } // end while
                } // end try
                // process problems with I/O
                catch (IOException ioException) {
                    ioException.printStackTrace();
                }
            }
        });
    } // end method runServer
    

    它适用于原始代码。我决定在接口中添加一些GUI元素,并使用Eclipse Luna 4.4.1添加了一个Application窗口。我添加了IP地址和端口号的输入。然后我添加了一个按钮' Open Connection'对于服务器GUI,另一个按钮“连接到服务器”#39;用于客户端GUI。

    现在我运行Server.java,直到我点击' Open Connection'按钮。然后按钮保持按下,尽管我发布并且表单没有响应。之后我运行Client.java并连接到服务器并获得连接成功'服务器的消息。我发送一些消息后关闭客户端窗口,然后突然所有消息都出现在服务器窗口上。

    现在我明白,服务器窗口的非响应是因为while ( true )循环。换句话说,该程序运行良好,但无法足够快地更新界面。我想用一个端口监听器来改变它,或者更快或更敏感的其他东西。

    如何更改?

    我已经改变了

    public void runServer() {
        // set up server to receive connections; process connections
        SwingUtilities.invokeLater(new Runnable() {...
    

    public void runServer() {
        // set up server to receive connections; process connections
        SwingUtilities.invokeLater(new Thread() {...
    

    但情况仍然不变。

    您可以访问我的代码

    ServerGUI.java @ http://pastebin.com/pVRi6EfC

    ClientGUI.java @ http://pastebin.com/HfftM159

    原始代码:

    Server.java @ http://pastebin.com/6Q5Z00gb

    Client.java @ http://pastebin.com/uCGFGknf

2 个答案:

答案 0 :(得分:2)

问题是您使用的是SwingUtilities.invokeLater。正如this answer所述,invokeLater执行应用程序主run内的Thread正文。由于您的用户界面也在此Thread中运行,因此您需要使用其他方法。

您希望将此无限循环放在Thread中并明确调用start,以便它不会阻止您的用户界面。

class MyChatServer extends Thread {
    public void run() {
        // the while loop
    }
}

然后,当您按下“打开连接”按钮时,可以启动Thread

MyChatServer server = new MyChatServer();
server.start();

如果没有明确创建新的Thread,您的应用只能使用一个Thread。此Thread将在UI和您需要执行的任何其他工作之间共享。因此,当您进行一些工作(例如while(true))时,只会占用您的Thread,您的用户界面将会冻结,直到再次获得控制权为止。

因此,通过创建新的Thread,您可以让UI保持控制而不是冻结。

答案 1 :(得分:1)

您的无限循环是忙碌的等待,这会阻止您的UI刷新。你有两个问题:

  • 忙碌的等待不是最好的方法
  • 等待阻止UI实现和事件处理

请等待alternatives

,而不是忙着等待

此外,您应该在引擎的不同线程中使用UI。 您可能还想阅读swing concurrency