2009-11-22 2 views
1

Я написал EchoServer, который отвечает строкой ack, если данные были отправлены соответственно.ObjectInputStream и ObjectOutputStream

Мой клиент выглядит так ... Для получения ответа от сервера «echoSocket» помещает полученные данные в мой ObjectIputStream. Только если я комментирую эти части из клиент работает

 echoSocket = new Socket(server_name, tcp_port); 
     System.out.println(" *** Connected to " + server_name + " ***"); 
     System.out.println("Press Enter to send your message."); 

     out = new ObjectOutputStream(echoSocket.getOutputStream()); 
     in = new ObjectInputStream(echoSocket.getInputStream()); 

     out.flush(); 

     String message = System.console().readLine(); 

     while(!message.equals("quit")) { 


      // problem     
      if (in.readObject().equals(ack)) 
       System.out.println("ACKed"); 
      in.close(); 
      // problem ends 
      out.flush(); 

      out.writeObject(message); 
      System.out.println("Sending: " + message);  
      message = System.console().readLine(); 
      out.flush(); 

     } 

ли кто-нибудь знает, почему он не будет посылать мои строки?

Спасибо, Marius

+0

Является ли ack обязательным для строкового литерала? Изменить на: if (in.readObject(). Equals ("ack")) – barrowc

ответ

3

Использование объектных потоков над гнездами на самом деле не рекомендуется идея. Вы можете рассмотреть полный веб-сервис или RMI.

Это может работать лучше, если вы читаете в буфер и убедитесь, что у вас есть все дело до того, как попытаться десериализовать потоки объектов.

+2

RMI стоит очень дорого. Иногда потоки + сокеты - лучшее решение. –

+0

Он * не будет * работать лучше, если вы читаете в буфер - тогда вам придется самостоятельно управлять границами объектов. Но вставка BufferedInputStream будет означать меньшее количество вызовов на системный вызов на уровне системы. Подобные тесты часто терпят неудачу из-за блокировки, возникающей при попытке чтения и записи одного и того же канала в одном потоке. –

1

Похоже, клиент пытается прочитать подтверждение, прежде чем он написал сообщение.

+0

, даже если я изменю заказ, клиент просто остановится. Ответ не является обязательным ... если нет ответа, он продолжает ждать. – wishi

+0

readObject() будет блокироваться до получения данных. Поэтому, если сервер никогда не признает, вы будете ждать всегда. Вы говорите, что ACK не является обязательным ... возможно, вы можете расширить, почему вы хотите ACK, если это не требуется. Как долго вы должны ждать его, прежде чем сдаваться? Почему эта петля даже заботится? – PSpeed

+0

@ wishi_ Я предлагаю вам остановить случайное перемещение вещей и ДУМАТЬ о том, что происходит. Как говорит @PSpeed, вызов операции чтения на входном потоке клиента приведет к блокировке до тех пор, пока он не получит данные (необязательные или нет) с сервера. –

1

Разделить «отправка» и «прием» кода в отдельные потоки, нить писателя может записываться в сокет, в то время как ваш другой поток блокируется при вызове readObject().

Если это будет длительный клиент, я бы также рекомендовал использовать DataInputStream и DataOutputStream более низкого уровня вместо ObjectInputStream/ObjectOutputStream, чтобы предотвратить удержание на возможно большой IdentityHashmap объектов.