Застрял в readLine (), даже если строка равна нулю - PullRequest
0 голосов
/ 07 декабря 2018

Я написал этот цикл на моем сервере, где он просто отправляет клиенту несколько строк:

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

У клиента есть еще один цикл для извлечения всех этих строк, но он никогда не выходит из него.Например, если я отправлю ему 4 строки, вывод будет:
-hi
-how
-are
-you
А затем после этой последней строки он зависнет, и я ничего не могу сделатькроме закрытия сервера.Когда я закрываю его, клиент выходит из режима ожидания.Этот цикл не работает:

        /* 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");

Вот код клиента с инкриминированным циклом:

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");

Вот код сервера:

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");
            }
        }
    }
}

1 Ответ

0 голосов
/ 08 декабря 2018

Основываясь на чтении вашего клиентского кода, похоже, что он заблокирован в ожидании другого сообщения и не возвращает ноль, потому что конец потока не достигнут.Тот факт, что он продолжается после завершения процесса сервера, подтверждает это.

Как отмечено в комментариях, вы должны убедиться, что закрыли PrintWriter на стороне сервера.Однако это само по себе не исправит это, поскольку поток находится в сокете, и пока сокет все еще открыт, он не будет возвращать ноль.

Вы можете использовать определенный элемент управлениястроки для передачи состояния назад и вперед (вещи, которые никогда не будут вводиться пользователем, просто чтобы убедиться, что раунд обмена данными завершен), а затем вместо проверки на нулевое значение вы проверяете, соответствует ли строка управляющей строке.Просто используйте эту технику с обеих сторон, чтобы передать управление назад и вперед, и убедитесь, что закрыли гнездо, когда закончите.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...