简体   繁体   English

卡在readLine()上,即使该行为空

[英]Stuck on readLine() even if the line is null

I wrote this loop in my server, where he just sends some strings to a client: 我在服务器中编写了这个循环,他只是在其中向客户端发送一些字符串:

PrintWriter out = new PrintWriter(incoming.getOutputStream(), true);
for (int j = 0; j < i; j++) {
    out.println(tmp[j]); // send the strings to the client
}

The client has another loop to retrieve all these strings but never exit from there. 客户端还有另一个循环来检索所有这些字符串,但从不退出。 For example, if I send him 4 strings the output will be: 例如,如果我给他发送4个字符串,则输出将是:
-hi -hi
-how -怎么样
-are -是
-you -您
And then after this last string it hangs and I cannot do anything else than closing the server. 然后,在最后一个字符串之后,它挂起了,除了关闭服务器,我无法做其他任何事情。 When I close it, the client exit from the while. 当我关闭它时,客户端从那一刻退出。 This is the loop that doesn't work: 这是无效的循环:

        /* PHASE 2: The client receives the ArrayList with the emails */
        BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));
        String line;
        String message[] = new String[5];
        for (int j=0; ((line = in.readLine()) != null) && (line.length())>0;) {
           System.out.println(line); //DEBUG
           message[j++] = line;
           if (j==5) {
                data = format.parse(message[3]);
                email.add(new Email((Integer.parseInt(message[0])), message[1], account, message[2], message[4], data));
                j=0;
            }
        }
        System.out.println("Out");

Here is the code of the client with the loop incriminated: 这是带有循环的客户端代码:

public void loadData() throws IOException, ClassNotFoundException, ParseException {

    try {
        connect();
        ArrayList<Email> email = new ArrayList<Email>();
        DateFormat format = new SimpleDateFormat("dd/MM/yyyy");
        Date data;

        /* PHASE 1: The client sends a string to the server */
        try {
            PrintWriter out = new PrintWriter(s.getOutputStream(), true);
            out.println(account+"\n"); // send the account name to server

            /* PHASE 2: The client receives the ArrayList with the emails */
            BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));
            String line;
            String message[] = new String[5];
            for (int j=0; ((line = in.readLine()) != null) && (line.length())>0;) {
                System.out.println(line); //DEBUG
                message[j++] = line;
                if (j==5) {
                    data = format.parse(message[3]);
                    email.add(new Email((Integer.parseInt(message[0])), message[1], account, message[2], message[4], data));
                    j=0;
                }
            }
            System.out.println("Out");

Here is the server code: 这是服务器代码:

class ThreadedEchoHandler implements Runnable {

    private Socket incoming;

    private String nomeAccount = "";

    public void run() {
        try {
            incoming = s.accept();
        } catch (IOException ex) {
            System.out.println("Unable to accept requests");
        }
        contenutoTextArea.append("Connected from: " + incoming.getLocalAddress() + "\n");
        textarea.setText(contenutoTextArea.toString());
        try {
            //PHASE 1: The server receives the email
            try {
                BufferedReader in = new BufferedReader(new InputStreamReader(incoming.getInputStream()));
                nomeAccount = in.readLine();
            } catch (IOException ex) {
                System.out.println("Not works");
            }

            //PHASE 2: I'm getting all the emails from the files
            File dir = new File("src/server/" + nomeAccount);
            String[] tmp = new String[100];
            int i = 0;
            for (File file : dir.listFiles()) {
                if (file.isFile() && !(file.getName().equals(".DS_Store"))) {
                    try (BufferedReader br = new BufferedReader(new FileReader(file))) {
                        String line;
                        while ((line = br.readLine()) != null) {
                            tmp[i++] = line;
                        }
                        br.close();
                    } catch (IOException ex) {
                        System.out.println("Cannot read from file");
                    }
                }
            }

            //PHASE 3: The server sends the ArrayList to the client
            PrintWriter out = new PrintWriter(incoming.getOutputStream(), true);
            for (int j = 0; j < i; j++) {
                out.println(tmp[j]); // send the strings to the client
            }

        } catch (IOException ex) {
            System.out.println("Cannot send the strings to the client");
        }

        //PHASE 4: Here I loop and wait for the client choise
        BufferedReader in;
        String op;
        boolean exit = false;
        try {
            in = new BufferedReader(new InputStreamReader(incoming.getInputStream()));
            while ((op = in.readLine()) != null) {
            System.out.println("OP: " + op);
            if (op.equals("Elimina")) {
                String tmp = in.readLine();
                contenutoTextArea.append("Ho eliminato la mail ").append(tmp).append(" \n");
                textarea.setText(contenutoTextArea.toString());
                File file = new File("src/server/" + nomeAccount + "/" + tmp + ".txt");
                file.delete();
            }
        }
            System.out.println("bbbbb");
        } catch (IOException ex) {
            System.out.println("Unable to read messages");
        } finally {
            try {
                incoming.close();
            } catch (IOException ex) {
                System.out.println("Cannot close the socket");
            }
        }
    }
}

Based on reading your client code, it looks like it's blocked waiting for another message, and it's not returning null because the end of the stream hasn't been reached. 基于读取您的客户端代码,看起来它已被阻止等待另一条消息,并且由于未到达流的末尾而未返回null。 The fact that it continues once you kill the server process validates this. 一旦终止服务器进程,该过程就会继续,这一事实证明了这一点。

As noted in the comments, you should make sure you close the PrintWriter on the server side. 如注释中所述,您应确保关闭服务器端的PrintWriter However, this by itself won't fix it, since the stream is on the socket, and as long as the socket is still open, this won't return null. 但是,这本身无法解决,因为流在​​套接字上,并且只要套接字仍处于打开状态,就不会返回null。

You can use specific control strings to communicate state back and forth (things that would never be user input, just to verify that round of communication is finished) then instead of checking for null, you'd check if the line matched the control string. 您可以使用特定的控制字符串来回通信状态(永远不会是用户输入的东西,只是为了验证通信是否已完成),然后检查该行是否与控制字符串匹配,而不是检查是否为空。 Simply use that technique on both sides to pass control back and forth, and make sure to close the socket when done. 只需在两侧使用该技术即可来回传递控制,并确保完成后关闭插座。

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

相关问题 我的Java代码经常陷入“ while((line = rd.readLine())!= null){”循环中。 如何优化代码 - My java code often stuck in a loop “while ((line = rd.readLine()) != null) {”. How to optimize the code BufferedReader readline 读取 null 即使文件中有文本 - BufferedReader readline reading null even though there is text in the file 即使文件有内容,readLine() 也会返回 null - readLine() returns null even though file has content BufferedReader#readLine()即使已读取一行也会挂起 - BufferedReader#readLine() hangs even though a line has been read BufferReader卡在readline()中 - BufferReader stuck in readline() PowerShell脚本卡在ReadLine()上 - PowerShell script is stuck on ReadLine() BufferedReader readLine() 卡住了 - BufferedReader readLine() stuck Java:while((line = bufferedReader.readLine())!= null)MISSING 2 LINES - Java: while((line = bufferedReader.readLine()) != null) MISSING 2 LINES 使用“ while(line = reader.readLine()!= null)”时,类型不匹配 - Type mismatch when using “while(line = reader.readLine() != null)” 即使没有达到EOF,randomAccessFile.readLine()在多次使用后仍返回null。 - randomAccessFile.readLine() returns null after many uses even though not reaching EOF?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM