我正在编写代码来模拟内存分布式数据库的结构。我有一个中央服务器类和一个从属服务器类。中央服务器实例与所有从属实例通信以从它们获取信息。 makeSlaveRequest() 方法是中央服务器类的一部分,如下所示:
private ArrayList<String> makeSlaveRequest(SlaveServer slave, String artist) {
int port = slave.getPort();
ArrayList<String> result = new ArrayList<String>();
try(Socket slaveConnection = new Socket("localhost", port)) {
System.out.println("Entered makeSlaveRequest");
PrintWriter outToSlave = new PrintWriter(slaveConnection.getOutputStream(), true);
BufferedReader inFromSlave = new BufferedReader(new InputStreamReader(slaveConnection.getInputStream()));
outToSlave.println(artist);
String line = inFromSlave.readLine();
while(line != null) { // I'm pretty sure that we're getting stuck here
if(line.equals("No songs by that artist")) {
break;
}
System.out.println("Reading from slave: " + line);
result.add(line);
System.out.println(result);
line = inFromSlave.readLine();
}
System.out.println("Slave connection closed");
slaveConnection.close();
} catch(UnknownHostException uhe) {
System.out.println("unkown host");
uhe.printStackTrace();
} catch(IOException ioe) {
System.out.println("IOException: " + ioe);
ioe.printStackTrace();
}
System.out.println(result);
return result;
}
所有对 System.out.println() 的调用纯粹是为了调试目的。
代码卡住的地方是 while 循环。从从属服务器读入最后一首相关歌曲后,我希望 while 循环终止并打印“从属连接关闭”,但是 while 循环永远不会终止。我认为这一定是因为 line 永远不会等于 null,但是,一旦从 slave 发送最后一首歌曲并由 readLine() 读入,我希望 line 等于 null。下面是SlaveServer的handleConnection()方法的代码,也就是与makeSlaveRequest()通信的方法:
protected void handleConnection(Socket connection) throws IOException {
BufferedReader inFromCentral = new BufferedReader(new InputStreamReader(connection.getInputStream()));
PrintWriter outToCentral = new PrintWriter(connection.getOutputStream(), true);
System.out.println("Entered the slave server handle connection method");
String reqArtist = inFromCentral.readLine();
System.out.println(reqArtist);
if(songDir.containsValue(reqArtist.trim())) {
System.out.println("Contains reqArtist");
List<String> songList = new ArrayList<String>();
System.out.println("songList created");
for(Map.Entry<String, String> entry : songDir.entrySet()) {
System.out.println("entered for loop");
if(entry.getValue().equals(reqArtist)) {
songList.add(entry.getKey());
System.out.println("entry added");
}
}
for(String song : songList) {
System.out.println("slave output: " + song);
outToCentral.println(song);
}
} else {
System.out.println("No Req Artist");
outToCentral.println("No songs by that artist");
}
System.out.println("flushing");
outToCentral.flush();
System.out.println("EOM");
}
}
需要注意的是,每个 SlaveServer 实例都在它自己的线程中运行,每当与 SlaveServer 建立连接时,它都会使用线程池中的线程来处理它。 CentralServer 也是一样。
为什么 while 循环没有终止?
最佳答案
readLine() 只会在到达 EOF 时返回 null,对于套接字连接而言,这将在远程端关闭时返回。如果奴隶不关闭连接并停止,你将永远循环(好吧, readLine() 会阻塞)。因此,您需要确定一种指示从属已完成的方法(如果您不希望它在完成时关闭套接字)。
关于java - 为什么这个 while 循环没有终止?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33848094/