简体   繁体   English

为什么这个while循环不终止?

[英]Why is this while loop not terminating?

I'm writing code to simulate the structure of an in memory distributed database. 我正在编写代码以模拟内存中分布式数据库的结构。 I have a central server class and a slave server class. 我有一个中央服务器类和一个从属服务器类。 The central server instance communicates with all of the slave instances to get information from them. 中央服务器实例与所有从属实例通信以从它们获取信息。 The method makeSlaveRequest() is part of the central server class and is shown below: 方法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;
        }

All calls to System.out.println() are purely for debugging purposes. 对System.out.println()的所有调用纯粹是出于调试目的。

The point the code gets stuck at is the while loop. 代码卡住的点是while循环。 Once the last relevant song has been read in from the slave server, I'm expecting the while loop to terminate and "Slave connection closed" to be printed, however the while loop never terminates. 从从属服务器读取完最后一首相关的歌曲后,我期望while循环终止,并且将打印“从属连接关闭”,但是while循环永远不会终止。 I think this must be due to the fact that line never equals null, however, I would expect line to equal null once the last song has been sent from the slave and read in by readLine(). 我认为这一定是由于行永远不会等于null的事实,但是,我希望一旦从从机发送了最后一首歌曲并通过readLine()读入,行就会等于null。 Here is the code for the SlaveServer's handleConnection() method, which is the method communicating with makeSlaveRequest(): 这是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");
        }
    }

It should be noted that each SlaveServer instance is running in it's own thread, and whenever a connection is made to SlaveServer, it uses a thread from a thread pool to handle it. 应当注意,每个SlaveServer实例都在其自己的线程中运行,并且每当与SlaveServer建立连接时,它都会使用线程池中的线程来处理它。 CentralServer is the same. CentralServer是相同的。

Why is the while loop not terminating? 为什么while循环不终止?

从服务器永远不会关闭连接/流,因此中央服务器无法知道在接收到的最后一行之后没有下一行,因此readLine()阻塞,等待从服务器发送下一行,或者以便关闭连接并因此到达流的末端。

readLine() will only return null when it reaches EOF, which for a socket connection will be when remote side closes. readLine()仅在到达EOF时才返回null,对于套接字连接,它将在远端关闭时返回。 If the slaves don't close connection and stop, you will be looping forever (well, readLine() will block). 如果从站不关闭连接并停止,则您将永远循环(好,readLine()将阻塞)。 So, you need to decide on a method that indicates that the slave is done (if you don't want it to close socket when it's done). 因此,您需要确定一个指示从属已完成的方法(如果您不希望它在完成后关闭套接字)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM