#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() является избыточным».