Не будет зацикливать чтение строк через ObjectInputStream в клиентском сокете

#java #sockets #objectinputstream

#java #сокеты #objectinputstream

Вопрос:

Я должен отправлять строки с сервера на сторону клиента по сокету на стороне сервера, у меня есть следующий код

 serverSocket=new ServerSocket(2004);
        socket=serverSocket.accept();
        System.out.println("request arrived");
        this.outStream=new ObjectOutputStream(socket.getOutputStream());
        outStream.flush();
        this.inStream=new ObjectInputStream(socket.getInputStream());

       //PoolTuningStrategy is an terface that is implemented by number of strategies

        for ( PoolTuningStrategy st : this.strategies ) {
                String name=st.getName();
            System.out.println("inside Loop " name);

              outStream.writeObject(name);
              outStream.flush();
            }

          outStream.writeObject("END NAMES...");
          outStream.flush();
  

Теперь на стороне сервера все имена печатаются на консоли правильно. Теперь на стороне клиента у меня есть следующий код.

 socket = new Socket("localhost", 2004);
System.out.println("Client starting");
this.outStream=new  ObjectOutputStream(socket.getOutputStream());
outStream.flush();
this.inStream=new   ObjectInputStream(socket.getInputStream());
do{
     name=(String)this.inStream.readObject();
     System.out.println(name);

  }while(name.equals("END NAMES..."));
  

Но на стороне клиента печатается только первая строка, а не все!
Пожалуйста, помогите мне

Ответ №1:

Вам не хватает! перед вашим тестом equals() в состоянии while.

Здесь нет «двусмысленности».

Ответ №2:

На стороне сервера убедитесь, что вы вызываете outStream.close() . Вам также не хватало !

Я бы рекомендовал изменить ваш код следующим образом:

 while( ! "END NAMES...".equals( (name=this.inStream.readObject())) ){
  

ИЛИ вот так

 while("END NAMES...".compareTo( (name=this.inStream.readObject())) != 0 ){
      System.out.println(name);

  }
  

Почему? 1) Используя «КОНЕЧНЫЕ ИМЕНА …».equals(…), вы избегаете исключения NullPointerException, и ваш код может корректно с этим справиться. 2) Вы избегаете ClassCastException . 3) Вы избегаете исключения IOException, если вы уже находитесь в конце потока. 4) Это более компактный код.

Кроме того, может не потребоваться вызывать flush(), если вы вызываете close() в потоке. Это может добавить дополнительную нагрузку за счет добавления вызовов функций. Обратите внимание, что мы не используем C / C . Java автоматически сбрасывается, когда буфер заполнен, и в конце (РЕДАКТИРОВАТЬ: когда вы его закрываете) потока.

Комментарии:

1. Вы не избежите исключения EOFException. Вы не можете. Никогда не нужно вызывать flush() перед close() , но это не сильно увеличивает «нагрузку». Ввод-вывод — это нагрузка на порядки.

2. Это зависит от того, что вы делаете, и если ваш алгоритм требует этого. Если ваш сервер разговаривает несколько минут, вам следует вызвать flush() . Он также вызывает его после каждого элемента, который он помещает в поток. Это НЕ C / C . Java будет сбрасываться, когда буфер заполнен или когда поток закрывается. Воспользуйтесь этим.

3. Вызов flush() непосредственно перед вызовом close() является избыточным. Я не понимаю, какое отношение к этому имеют C или C .

4. Я думаю, что мы говорим об одном и том же на самом деле. Я согласен с тем, что «вызов flush() непосредственно перед вызовом close() является избыточным».