BufferedWriter не отправляет текст, если поток не закрыт - PullRequest
2 голосов
/ 25 июля 2011

У меня есть сервер, который общается с клиентом.

Сервер является многопоточным, и этот поток создается с сокетом и буферизованным считывателем, подключенным к сокету, когда первая строка, прочитанная из сокета, является «запросом»:

public class scriptComm implements Runnable {

private Socket sock;
private Socket sock2;
private Connection connection;
private BufferedReader reader;

@Override
public void run() {
    try {

        String name = reader.readLine();
        String password = reader.readLine();

        String line;
        connection = methods.connectToDatabase();
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(sock.getOutputStream()));
        if (connection != null && name != null && password != null) {
            try {
                ResultSet rs = connection.createStatement().executeQuery(
                        "SELECT name, password, doupdate FROM accounts "
                        + "WHERE name = '" + name + "' AND doupdate = 'yes'"
                        + " AND password = '" + password + "'");
                if (rs.next()) {
                    methods.log("worked");
                    bw.write("accept");
                    bw.flush();
                    bw.close();
                    reader = new BufferedReader(new InputStreamReader(sock2.getInputStream()));
                    if ((line = reader.readLine()) != null) {
                        mainFrame.jTextArea1.append("line \n");
                        connection.createStatement().executeUpdate(
                                "UPDATE accounts SET updatetext = '" + line + "' "
                                + "WHERE name = '" + name + "'");
                    }else{
                        mainFrame.jTextArea1.append("No text received \n");
                    }
                } else {
                    bw.write("decline");
                    bw.flush();
                }
                bw.close();
                rs.close();
            } catch (SQLException ex) {
                methods.log("Error when executing statement in scriptComm");
                ex.printStackTrace();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        } else {
            methods.log("missing values in scriptComm");

        }
    } catch (IOException ex) {
    }


}

public scriptComm(Socket sock, BufferedReader reader) {
    this.sock = sock;
    this.sock2 = sock;
    this.reader = reader;
}}

Вы можете заметить, что я закрываю поток bw после того, как он пишет "accept".

Это связано с тем, что клиент просто висит там, как будто он не получает никаких входных данных, когда поток не закрыт.

Клиент:

        try{
        String line;
        Socket sock = new Socket("myipaddresshere",portnumber); 
        PrintWriter writer = new PrintWriter(sock.getOutputStream());
        BufferedReader reader = new BufferedReader(new InputStreamReader(sock.getInputStream()));
        writer.println("script");
        writer.flush();
        writer.println(jTextField1.getText());
        writer.flush();
        writer.println(jTextField2.getText());
        writer.flush();
        if ((reader.readLine()).equals("accept")) {
            writer.write("testing123");
            writer.flush();
            writer.close();
        } else {
            jTextArea1.append("fail");

        }
        reader.close();
        writer.close();
    }catch(IOException e){
        jTextArea1.append("Server not available. Please try again later.");
    }

Когда поток не закрывается после записи «accept» с сервера, это как если бы клиент просто сидел на булевой проверке if (reader.readLine (). Equals («accept»)) (и да, на потоке сбрасывается на стороне сервера).

Однако, когда поток также закрыт на стороне сервера, он проходит логическую проверку и продолжает запись строки "testing123" в поток. Сервер, очевидно, не может прочитать эту строку, поскольку поток сокетов был закрыт, когда закрылся BufferedReader. Как вы можете заметить, я попытался реплицировать сокет, просто создав другую переменную с именем sock2, но, похоже, это соединение также закрывается (имеет смысл).

Примечание: при соединении с неправильным пользователем / паролем (т.е. когда rs.next () возвращает false), он записывает «отклонение» в поток, и клиент получает это.

Действительно запутался об этом ..

Спасибо, Майк.

Ответы [ 2 ]

3 голосов
/ 25 июля 2011

Обратите внимание, запись не записывает новую строку, а вы пытаетесь прочитать целые строки. Вам нужно написать символ новой строки, прежде чем вы сбросите.

Либо используйте BufferedWriter. newLine () , либо добавьте "\n" к строкам, которые вы пишете.

2 голосов
/ 25 июля 2011

Я оставлю это как совет:

Когда вы хотите записать символы в поток, вы всегда должны использовать OutputStreamWriter и InputStreamReader с явной кодировкой символов.Я рекомендую "UTF-8".

Как написано, ваш код будет записывать и читать с кодировкой платформы по умолчанию.Это будет работать, вплоть до того времени, когда кто-то в Китае будет запускать клиент под Windows, а кто-то в США будет запускать сервер под Linux (и в зависимости от того, что вы отправляете, он может сломаться гораздо раньше).

...