Сокеты, BufferedReader.readline () - почему поток не готов? - PullRequest
2 голосов
/ 19 декабря 2011

Я изучаю Java, и я столкнулся с некоторыми проблемами с сокетами.Я разработал простое клиент-серверное приложение - своего рода тук-тук, оно выполняет 4 шага:

  1. клиент отправляет некоторые сообщения на сервер
  2. сервер получает их и сохраняет в файл
  3. сервер отправляет обратно клиенту некоторые другие сообщения
  4. клиент получает их и также сохраняет в файл

Проблема появляется на шаге # 4: клиент не получает сообщения и никогдавыходит из цикла:

while ((inStr = in.readLine()) != null) {
    writer.println(inStr);
}

где в это тип BufferedReader:

    try {
        socket = new Socket(ipAddress, 4444);
        out = new PrintWriter(socket.getOutputStream(), true);
        in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
    } catch (UnknownHostException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }

На стороне сервера отправляются сообщения:

    try {
        socket = srvSocket.accept();
        out = new PrintWriter(socket.getOutputStream(), true);          
        in = new BufferedReader(new InputStreamReader(socket.getInputStream()));                
    } catch (IOException e) {
        e.printStackTrace();
    }

...

    out.println("test from server #1");
    out.println("test from server #2");

на стороне клиента я смотрел in.ready() - он возвращает false.На стороне сервера я смотрю out.checkError() - он возвращает true;

Что я делаю не так - почему поток пуст?

Любая помощь приветствуется!:)

Ответы [ 2 ]

2 голосов
/ 19 декабря 2011

Вы используете public PrintWriter(OutputStream out, boolean autoFlush), который будет автоматически обновляться в новой строке или println. Он не очищается автоматически после каждой записи. Вы должны очищать после каждой записи.

Вот javadoc для параметра autoFlush конструктора: логическое значение;если true, методы println, printf или format очистят буфер вывода

0 голосов
/ 19 декабря 2011

Это может / не может решить вашу проблему.Но попробуйте сохранить все в блоке Try Catch.Например, инициализация вашего ServerSocket, блоки записи и т. Д. Если произойдет какая-либо ошибка, вы, возможно, не сможете использовать модуль записи, поэтому нет смысла инициализировать его.
Вы можете попробовать записать в стандартный поток вывода для отладки вместо файла.Ниже код для сервера / клиента является второстепенным вариантом вашего и его работы.

Сервер:

    Socket socket;
    ServerSocket srvSocket;
    BufferedReader in;
    PrintWriter out;
    try {
        srvSocket=new ServerSocket(4444);
        socket = srvSocket.accept();
        out = new PrintWriter(socket.getOutputStream(), true);          
        in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        out.println("test from server #1");
        out.println("test from server #2");
    } catch (IOException e) {
        e.printStackTrace();
    }

Клиент

    Socket socket;
    BufferedReader in;
    PrintWriter out;
    String inStr;
    try {
        socket = new Socket("127.0.0.1", 4444);
        out = new PrintWriter(socket.getOutputStream(), true);
        in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        while ((inStr = in.readLine()) != null) {
            System.out.println(inStr);
        }
    } catch (UnknownHostException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...