2016-04-13 9 views
3

У меня есть сервер и клиент в моей маленькой демонстрационной программе, где я отправляю некоторые строковые данные от Клиента на Сервер и после этого пересылает эти данные для Клиента, который также записывает его на консоль. Меня смутил метод Flush PrtintWriter, который, согласно документации JAVA, - сбрасывает поток. После некоторых исследований я знаком с концепцией autoflash: когда параметр autoFlash является истинным, println, printf или методы форматирования будут очищать выходной буфер. Единственное, что я не понимаю здесь, - это то, почему я должен использовать метод Flush PrintWriter в цикле, а не после цикла. (В моем случае я использую PrintWriter на стороне сервера.) Autoflash делает то же самое, потому что метод println() также находится в цикле. Когда я использую flush после цикла, мои строковые данные не отображаются на консоли. Благодарим вас за руководство и заблаговременно!В случае PrintWriter, почему я должен скрываться в цикле, а не после цикла?

Клиент:

public class ClientDemo { 
public static void main(String[] args) throws IOException { 

    final String CLIENTNAME = "<CLIENT>:"; 
    final String SERVERADDRESS = "localhost"; 
    final int PORT = 12312; 

    try { 
     Socket socket = new Socket(SERVERADDRESS, PORT); 
     PrintWriter out = 
      new PrintWriter(socket.getOutputStream(), true);     
     Scanner scanner = new Scanner(socket.getInputStream()); 

     System.out.println(CLIENTNAME + "Client starts"); 
     List<String> lista = getList(); 

     for(String userInput : lista){ 
      out.println(userInput); 
      System.out.println("echo: " + scanner.nextLine()); 
     } 

    } catch(IOException e) { 
     System.out.println(CLIENTNAME + "Error connecting to the server:" + e.getMessage()); 
    } 
} 

    private static List<String> getList(){ 
     List<String> result = new ArrayList<>(); 
     result.add("egy"); 
     result.add("ketto"); 
     result.add("harom"); 
     result.add("negy"); 

     result.add("ot"); 
     result.add("hat"); 
     result.add("het"); 
     result.add("nyolc"); 
     result.add("kilenc"); 
     result.add("tiz"); 

     return result; 
    } 
} 

Сервер:

public class ServerDemo { 
public static void main(String args[]) throws IOException { 

    final int PORT = 12312; 
    final String SERVERNAME ="<SERVER>:"; 

    try { 
     ServerSocket serverSocket = new ServerSocket(PORT); 
     Socket socket = serverSocket.accept(); 
     PrintWriter printWriter = new PrintWriter(socket.getOutputStream()); 
     Scanner scanner = new Scanner(socket.getInputStream()); 

     System.out.println(SERVERNAME + "Server starts..."); 

     String inputLine; 
     while(scanner.hasNext()) { 
      inputLine = scanner.nextLine(); 
      printWriter.println(inputLine); 
      printWriter.flush(); 
     } 

    } catch (IOException e) { 
     System.out.println(SERVERNAME + "Error handleing client..."); 
    } 
    } 
} 

ответ

2

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

+0

Прежде всего, спасибо за ваш ответ. Во-вторых, не могли бы вы дать мне более глубокое объяснение того, как я могу блокировать ввод-вывод, делая флеш в цикле? Потому что, если я удалю линию флеша, список строк не появится в консоли. Мой учитель также предупредил меня использовать метод флеша. и, как вы можете видеть, я не использую autofalsh или не закрываю в моем примере. Еще раз заблаговременно! – F3R1

+1

Вы должны попытаться закрыть объект PrintWriter в блоке finally сразу после блока catch. Прямо сейчас вы не закрываете ресурс PrintWriter. Если вы закроете ресурс, он также очистит его до его закрытия. В этот момент все строки в буфере будут сброшены (записаны) в пункт назначения. Попробуйте добавить блок finally и закройте ресурс PrintWriter. Вы должны увидеть вывод на консоли. Вы также можете использовать новый оператор Java 7 try-with-resources, так что вам не нужно закрывать какие-либо ресурсы, реализующие интерфейс AutoClosable. – VHS

+0

Если я закрою ресурс в блоке finally и удаляю флеш из кода или переместите его после цикла, к сожалению, он также выполняет ту же ошибку, и я не могу видеть вывод на консоли. Я знаю инструкцию try-with-resource, я переписываю код с ним и тот же самый симптом. Если флеш находится в цикле, выход находится на консоли ... если он удален из цикла или после цикла я не вижу выход. (Кстати, я ценю вашу помощь, я уже дал вам право голоса. После того, как я заработаю магическую 15-ти высокую репутацию, вы это увидите. :)) – F3R1