我对套接字很新,并且以这种方式使用线程。
我遇到了扫描器等待用户输入和输入流读取器同时等待套接字通信的问题。我的程序正在尝试与客户端/服务器系统进行通信,并且工作正常,但是我也希望能够通过扫描仪或类似的东西直接将命令输入控制台。然而,主线程的while循环阻塞了套接字通信,而扫描器在inputThread的while循环中阻塞。
我的问题是,如果我在控制台中发送命令来关闭服务器(将bool'running'设置为false),主线程的while循环仍然等待套接字通信输入。一旦它收到任何消息,它将从while循环中逃脱,因为bool'running'被设置为false,但是只有在发送任何消息之后,由于它在检查while条件之前等待一个消息。
我的另一个问题基本上是相同的概念,但在inputThread的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();
感谢您阅读
答案 0 :(得分:0)
第一个问题是ServerSocket::accept
电话。它是阻塞的,但没有响应中断(如果它被声明抛出InterruptedException
)。立即解除阻塞的方法是从另一个线程close套接字。 accept()
调用将立即引发SocketException
。
第二个问题实际上更容易解决:while循环也应该检查running
标志。因此,当给出命令行输入来停止程序时,输入线程不会开始等待下一个命令。