尝试从输入流中检索文本时,应用程序挂起 [英] Application hangs when attempting to retrieve text from an inputstream

查看:151
本文介绍了尝试从输入流中检索文本时,应用程序挂起的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

情况

Situation

我一直在创建一个程序来在局域网中的两台计算机之间交换消息。一台计算机将自己标识为服务器而另一台计算机标识为客户端。启动时,如果用户希望作为客户端连接到该计算机,则必须输入另一台计算机的主机和端口。
它的工作原理设置是非常基本的:你输入你的信息,点击输入,它会显示在你自己的屏幕上。之后,您的对话伙伴必须单击按钮才能检索最新消息,并且它应显示在他的屏幕上。这种情况一直持续到有人离开。

I've been creating a program to exchange messages between two computers in the LAN. One computer identifies itself as the server while the other is a client. Upon startup, the user has to enter the Host and the Port of another computer, should he wish to connect as a client to that machine. The setup of how it works is very basic: You type your message, hit enter and it shows up on your own screen. After that your conversation partner has to click a button to retrieve the latest messages and it should show up on his screen. This goes on untill someone leaves.

问题

Problem

程序正确启动并询问连接设置。之后,我在两台计算机上启动连接,事情似乎很顺利(建立连接后,标签会显示您的状态,例如客户端或服务器,是(1))。当我输入消息并发送消息时,事情继续正常,输出将被写入发送者的屏幕,并且不会发生意外行为。

The program launches correctly and asks for the connection settings. After that I initiate the connection on both computers and things seem to go fine (after the connection is established, a label shows you what your status, e.g. Client or Server, is (1)). Things continue looking fine when I enter a message and send it, the output gets written to the sender's screen and no unexpected behaviour occurs.

当我想在另一台计算机上检索消息时,该程序完全冻结。 GUI中没有任何对象可以点击,也没有显示输出。

When I want to retrieve the messages on the other computer, the program completely freezes. No objects in the GUI are clickable and no output is shown.

代码

Code

假设连接已正确建立(参见(1)),我将概述下面发送消息的过程,同时省略非必要部分。

Assuming the connection is correctly established (see (1)), I will outline the process of sending a message below while leaving out the non-essential parts.

GuiApplication.java

private void sendMessage() {
    connection.sendMessage(message);
    showMessage(message);
}

Connection.java
public void sendMessage(String message) {
    if (isClient()) {
        client.sendMessage(message);
    } else if (isServer()) {
        server.sendMessage(message);
    }
}

Client.java
public void sendMessage(String message) {
    outbound = new PrintWriter(socket.getOutputStream(), true); // Defined outside this method
    outbound.println(message);
}

发送消息的过程非常简单,但我想要包含它以防我忽略了什么。

The process of sending a message is pretty straightforward, but I wanted to include it just in case I've overlooked something.

以下是我为检索新消息而创建的代码。这个概念很简单:我检查是否有新消息,如果有,我会检索它们。

What follows is the code I've created to retrieve the new messages. The concept is simple: I check if there are any new messages and if there are, I retrieve them.

GuiApplication.java
if (connection.hasNewMessage()) {
    message = connection.retrieveMessage();
}
showMessage(message);

第一部分( connection.hasNewMessage())将检查程序是运行客户端还是服务器并调用相应的 retrieveMessage()

The first part (connection.hasNewMessage()) will check whether or not the program is either running the client or the server and call the appropriate retrieveMessage().

Client.java
public String retrieveMessage() throws IOException {
    inbound = socket.getInputStream(); // Defined outside this method
    return IOUtils.toString(inbound, "UTF-8");
}

首先,我尝试使用 BufferedReader 使用 InputStreamReader 并调用 readLine()方法,但决定试用commons.io方法一旦我注意到它不起作用(与我目前面临的问题相同)。

At first I've tried this with a BufferedReader using an InputStreamReader and calling the readLine() method, but decided to try out the commons.io method once I noticed it didn't work (the same problem as I am currently facing).

问题

Question

现在已经很清楚:为什么我的程序在我点击一个检索新邮件的按钮时挂起?

It's been made pretty clear by now: why does my program hang the moment I click a button which retrieves new messages?

外部

External

我不确定它是不是很皱眉,但这里是 github存储库,以防你需要更好的概述,虽然我相信必要的代码片段在那里。

I'm not sure if it's frowned upon, but here's the github repository in case you wanted a better overview, although I believe the necessary code snippers are there.

推荐答案

我确实看了你的代码,而且我怀疑你的问题与代码完全无关你发布了。您的GUI完全忽略Swing线程规则,并在主Swing事件线程上调用长时间运行的任务,称为 E vent D ispatch T hread或 EDT 。由于此线程负责所有Swing绘图和用户交互,因此您的GUI无法执行此操作并完全冻结。

I did look at your code, and as I suspected, your problem has absolutely nothing to do with the code you've posted. Your GUI completely ignores Swing threading rules, and calls long-running tasks on the main Swing event thread known as the Event Dispatch Thread or EDT. Since this thread is responsible for all Swing drawing and user interaction, your GUI is prevented from doing this and becomes completely frozen.

请阅读 Swing中的并发有关详细信息。

下次请发布 sscce ,这样我们就不必深入研究大量的源代码! SSCCE的关键是消除对您手头的问题不重要的所有代码。这不容易做,并且需要你做很多工作才能创建,所以它有足够的代码来运行,但不能太淹没我们的代码,但是你要求志愿者帮助你免费时间,所以不要求太多。

And next time, please post an sscce so we don't have to dive into a huge amount of your source code! The key to the SSCCE is to eliminate all code not essential to your problem at hand. This is not easy to do and will require a lot of work from you to create, so that it has enough code to run, but not too much as to drown us in code, but then you are asking volunteers to help you on their free time, so it's not asking too much.

祝你好运!

这篇关于尝试从输入流中检索文本时,应用程序挂起的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆