[英]BufferedReader readLine() stuck
我正在编写一个在无限循环中工作的 TCP 多客户端/服务器应用程序。
怎么了:
预期结果:
我知道一旦我关闭套接字, BufferedReader
就会停止读取行。 然而,这不是我们想要的,因为它必须无限工作。
如何退出循环?
客户端方法:
public class Client {
private final Socket clientSocket;
private final BufferedReader clientInput;
private final PrintWriter clientOutput;
private final BufferedReader keyboardInput;
public Client() throws IOException {
this.clientSocket = new Socket(InetAddress.getLocalHost(), 13370);
this.clientInput = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
this.clientOutput = new PrintWriter(clientSocket.getOutputStream(), true);
this.keyboardInput = new BufferedReader(new InputStreamReader(System.in));
}
public static void main(String[] args) throws IOException {
Client client = new Client();
client.init();
}
private void init() {
try {
while (true) {
System.out.print("> ");
String args = keyboardInput.readLine().trim().replaceAll("\\s+", " ");
clientOutput.println(args.toUpperCase());
// the loops doesn't seem to stop after reading all input lines
String line;
while ((line = clientInput.readLine()) != null) {
System.out.println(line);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
public class ClientHandler implements Runnable {
private final int id;
private final Socket clientSocket;
private final PrintWriter serverOutput;
private final BufferedReader serverInput;
// private final ClientFiles clientFiles;
public int getId() {
return id;
}
public ClientHandler(int id, Socket clientSocket) throws IOException {
this.id = id;
this.clientSocket = clientSocket;
this.serverInput = new BufferedReader(new InputStreamReader(this.clientSocket.getInputStream()));
this.serverOutput = new PrintWriter(this.clientSocket.getOutputStream(), true);
// this.clientFiles = new ClientFiles(id, clientSocket);
}
@Override
public void run() {
try {
String command;
while ((command = serverInput.readLine()) != null) {
executeCommand(command.split(" "));
}
} catch (IOException e) {
e.printStackTrace();
} finally {
closeConnection();
removeFromHosts();
}
}
private void executeCommand(String[] input) throws IOException {
String command = input[0];
// String option = input[1];
switch (command) {
case "COMMANDS": {
getCommands();
break;
}
// case "LIST_LOCAL": {
// listFiles();
// break;
// }
// case "LIST_FILES": {
// listFiles(option);
// }
// case "PULL": {
// pull(clientSocket, option);
// }
// case "PUSH": {
// push(clientSocket, option);
// }
case "DISCONNECT": {
closeConnection();
break;
}
default: {
write("Invalid command.");
getCommands();
break;
}
}
}
private String read() throws IOException {
return serverInput.readLine();
}
private void write(String message) {
serverOutput.println(message);
}
private void getCommands() {
write("AVAILABLE COMMANDS:");
write("\tCOMMANDS");
write("\t\tlists available commands");
write("\tLIST_HOSTS");
write("\t\tlists hosts connected to server");
write("\tLIST_FILES");
write("\t\tlists files from all hosts connected server");
write("\tLIST_LOCAL");
write("\t\tlists local files");
write("\tLIST_FILES [HOSTS]...");
write("\t\tlists files from provided hosts connected server");
write("\tPULL [HOST] [FILE]");
write("\t\tdownloads file from host");
write("\tPUSH [HOST] [FILE]");
write("\t\tuploads file to host");
write("\tDISCONNECT");
write("\t\tdisconnects client from server");
}
private void closeConnection() {
try {
serverInput.close();
serverOutput.close();
clientSocket.close();
removeFromHosts();
} catch (IOException e) {
e.printStackTrace();
}
}
private void removeFromHosts() {
Server.getClients().remove(this);
}
}
服务器只接受新客户端并启动新线程。
public class Server {
private static final AtomicInteger count = new AtomicInteger(1);
private static final ArrayList<ClientHandler> clients = new ArrayList<>();
public static void main(String[] args) {
Server.init();
}
public static void init() {
System.out.println("Opening server socket...");
try (
ServerSocket serverSocket = new ServerSocket(13370)
) {
System.out.println("Server socket opened at port: " + serverSocket.getLocalPort());
while (true) {
System.out.println("Waiting for client connection...");
Socket clientSocket = serverSocket.accept();
System.out.println("Client connected.");
ClientHandler client = new ClientHandler(count.getAndIncrement(), clientSocket);
clients.add(client);
System.out.println(clients);
new Thread(client, "client-" + client.getId()).start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
public static ArrayList<ClientHandler> getClients() {
return clients;
}
}
您的客户正在等待更多线路。 在您的代码中
while ((line = clientInput.readLine()) != null) {
System.out.println(line);
}
如果服务器没有关闭连接,clientInput.readLine() 将永远不会返回 null。 执行停止等待更多数据。
我建议实施一个解决方案,例如插入一个空行或一个特殊字符来向客户端发出对命令的响应已完成的信号。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.