我正在编写代码来模拟内存分布式数据库的结构。我有一个中央服务器类和一个从服务器类。中央服务器实例与所有从属实例通信以从中获取信息。方法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循环终止并且&#34; Slave connection off&#34;要打印,但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循环没有终止?
答案 0 :(得分:2)
从属设备从不关闭连接/流,因此中央服务器无法知道在收到的最后一行之后没有下一行,因此if (store.load()) {
try {
for (String name : store.getGestureEntries()) {
if (name.equals("name of the entry you want to delete")) {
Gesture gesture = store.getGestures(name).get(0);
store.removeGesture(name, gesture);
store.save();
}
}
}catch (Exception e){
System.out.println(e.getMessage());
}
}
会阻塞,等待下一行被发送由奴隶,或连接关闭,从而达到流的结束。
答案 1 :(得分:2)
readLine()仅在到达EOF时返回null,对于套接字连接,当远程端关闭时。如果从站没有关闭连接并停止,那么你将永远循环(好吧,readLine()将阻塞)。因此,您需要确定一个指示从属设备已完成的方法(如果您不希望它在完成时关闭套接字)。