当前位置: 首页 > 知识库问答 >
问题:

Java在侦听主线程中的套接字时读取线程中的控制台输入

岳曦
2023-03-14

我对套接字和以这种方式使用线程相当陌生。

我遇到了一个问题,一个扫描器在等待用户输入,一个输入流阅读器在等待套接字通信。我的程序试图与客户机/服务器系统通信,这很好,但我也希望能够通过扫描仪或类似的东西直接将命令输入控制台。但是,主线程的while循环阻塞了套接字通信,而扫描器阻塞了InputThread的while循环。

我的问题是,如果我在控制台中发送命令关闭服务器(将布尔'running'设置为false),主线程的while循环仍然等待套接字通信输入。一旦它接收到任何消息,它就会逃离while循环,因为bool'running'被设置为false,但只有当任何消息被发送时,它才会在检查while的条件之前等待消息。

我的另一个问题是基本相同的概念,但在InputThread的while循环中。如果主线程的while循环中断,那么输入线程仍然会阻止扫描器,直到它接收到用户输入。一旦它接收到任何用户输入,它就会因为线程被中断而脱离while循环(while循环的条件)。

因此,为了让我的程序退出,我必须通过套接字和用户输入发送“重启服务器”消息,当我想以任何一种方式发送它时,程序才能正确退出。

我怎么解决这个问题?我会假设当我接收到结束服务器的套接字时取消扫描器的阻塞,但我如何做到这一点?我觉得有更好的方法,有什么想法吗?

inputThread = new Thread(new Runnable() {
    @Override
    public void run() {
        Logger.log("Starting input thread...");
        while(!Thread.currentThread().isInterrupted()) {
            try {
                scanner = new Scanner(System.in);
                String reply = runCommand(scanner.nextLine());
                Logger.log(reply);
                if(reply.equals("server restarted")) {
                    // TODO: Cancel socket input blocking?
                }
            } catch(Exception e) {
                e.printStackTrace();
            }
        }
        Logger.log("Closing input thread...");
    }
});
inputThread.start();
ServerSocket socket = null;
InputStreamReader inputStream = null;
BufferedReader input = null;
try {
    int port = getPort();
    socket = new ServerSocket(port);
    Logger.log("Server running on port " + port);
    while(running) {
        connection = socket.accept();
        inputStream = new InputStreamReader(connection.getInputStream());
        input = new BufferedReader(inputStream);
        String reply = runCommand(input.readLine());
        if(reply.equals("server restarted")) {
            // TODO: Cancel scanner input blocking?
        }
        reply(reply);
    }
} catch(Exception e) {
    e.printStackTrace();
} finally {
    if(socket != null) {
        try {
            socket.close();
        } catch(IOException e) {
            e.printStackTrace();
        }
    }
    if(connection != null) {
        try {
            connection.close();
        } catch(IOException e) {
            e.printStackTrace();
        }
    }
    if(inputStream != null) {
        try {
            inputStream.close();
        } catch(IOException e) {
            e.printStackTrace();
        }
    }
    if(input != null) {
        try {
            input.close();
        } catch(IOException e) {
            e.printStackTrace();
        }
    }
    if(response != null) {
        try {
            response.close();
        } catch(IOException e) {
            e.printStackTrace();
        }
    }
}
inputThread.interrupt();

谢谢你的阅读

共有1个答案

须旭
2023-03-14

第一个问题是ServerSocket::Accept调用。它正在阻塞,但不响应中断(如果是的话,它将被声明为抛出interruptedexception)。立即解除阻塞的方法是从另一个线程关闭套接字。然后,accept()调用将立即抛出SocketException

第二个问题实际上更容易解决:while循环也应该检查running标志。因此,当给出命令行输入以停止程序时,输入线程不会开始等待下一个命令。

 类似资料:
  • 问题内容: 我正在测试本地计算机上的套接字。我正在尝试使用线程在一个程序中同时运行套接字和服务器。我的服务器是回显服务器,因此它可以将收到的所有消息发回。我的问题是,当我同时在客户端和服务器上启动两个线程时,当它们到达我从输入流读取的部分时,它们将“冻结”。它可以很好地工作到客户端发送消息的那部分。然后,它停止了,因为似乎客户端正在等待消息,服务器也是如此,即使我已经通过写入输出流向服务器发送了消

  • 我正在编写一个简单的套接字编程应用程序,它使用一台服务器和一个客户端。我试图启动一个线程(从客户端文件中),从套接字输入流中读取输入,这样我就可以将消息写入服务器,同时读取并打印到屏幕上。然而,当我运行我的代码时,我的代码卡在 在< code>InputReader.java文件中,读取无输入? 我的代码如下,请帮忙。 简单服务器1.java SimpleClient1.java 输入读取器.ja

  • 问题内容: 我意识到在SO上也有类似的问题,但是它们并不能完全解决我的问题。 我想要一个给定Class对象的方法,该方法将在该Class(如果存在)上调用“ main”方法,即public static void main,并捕获该main方法的控制台输出。进行调用的类是非守护线程。 我已经有部分代码了,但是我不确定如何捕获控制台输出,最重要的是,如何仅捕获此特定线程的输出。这是我到目前为止的内容

  • 问题内容: 如果我有多个go例程,并且其中两个或两个以上例程决定需要打印某些内容,那么它们是否可能彼此中断? 例如: 是否有可能一个常规程序开始打印(),而另一个常规程序中断()和原始装订()? 我尝试自己运行它并检查输出,它 看起来 不错,但是如何确定? 问题答案: 是的,有可能,尽管GOMAXPROCS = 1不会显示任何内容。当使用更多goroutine,更大的行和更多的线程运行时,它们将显

  • 问题内容: 我正在Android中编写一个活动,用户可以在其中修改SQL数据库。用户界面由一个EditText(用户在其中输入名称)和一个Seekbar(用户在其中输入用户的吸引力)组成。在下面有很多按钮:添加,编辑,查看,删除。 当用户单击“编辑”按钮时,将显示一个输入对话框,要求用户输入记录号。完成后,将加载该记录。 我遇到的问题是,将显示输入对话框,并且当用户输入记录号时,其余的编辑方法将继