为什么这个while循环没有终止?

时间:2015-11-21 20:11:42

标签: java network-programming

我正在编写代码来模拟内存分布式数据库的结构。我有一个中央服务器类和一个从服务器类。中央服务器实例与所有从属实例通信以从中获取信息。方法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循环没有终止?

2 个答案:

答案 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()将阻塞)。因此,您需要确定一个指示从属设备已完成的方法(如果您不希望它在完成时关闭套接字)。

相关问题