java.io.StreamCorruptedException: неверный заголовок потока: 7371007E - PullRequest
20 голосов
/ 30 мая 2010

У меня есть клиент-серверное приложение, которое взаимодействует с помощью объектов.
когда я отправляю только один объект с клиента на сервер, все работает хорошо.
когда я пытаюсь отправить несколько объектов один за другим в одном потоке, я получаю

StreamCorruptedException.  

Может ли кто-нибудь указать мне причину этой ошибки?

метод записи клиента

   private SecMessage[] send(SecMessage[] msgs) 
   {
     SecMessage result[]=new SecMessage[msgs.length];
      Socket s=null;
      ObjectOutputStream objOut =null;
      ObjectInputStream objIn=null;
      try
      {
       s=new Socket("localhost",12345);
       objOut=new ObjectOutputStream( s.getOutputStream());
       for (SecMessage msg : msgs) 
       {
            objOut.writeObject(msg);
       }
       objOut.flush();
       objIn=new ObjectInputStream(s.getInputStream());
       for (int i=0;i<result.length;i++)
            result[i]=(SecMessage)objIn.readObject();
      }
      catch(java.io.IOException e)
      {
       alert(IO_ERROR_MSG+"\n"+e.getMessage());
      } 
      catch (ClassNotFoundException e) 
      {
       alert(INTERNAL_ERROR+"\n"+e.getMessage());
      }
      finally
      {
       try {objIn.close();} catch (IOException e) {}
       try {objOut.close();} catch (IOException e) {}
      }
      return result;
 }

метод чтения с сервера

//in is an inputStream Defined in the server
SecMessage rcvdMsgObj;
rcvdMsgObj=(SecMessage)new ObjectInputStream(in).readObject();
return rcvdMsgObj;

и класс SecMessage

public class SecMessage implements java.io.Serializable
{
 private static final long serialVersionUID = 3940341617988134707L;
 private String cmd;
    //... nothing interesting here , just a bunch of fields , getter and setters
}

Ответы [ 3 ]

10 голосов
/ 30 мая 2010

Если вы отправляете несколько объектов, часто проще всего поместить их в какой-нибудь держатель / коллекцию, например Object[] или List. Это избавляет вас от необходимости явно проверять конец потока и обеспечивает явную передачу количества объектов в потоке.

РЕДАКТИРОВАТЬ: Теперь, когда я отформатировал код, я вижу, что у вас уже есть сообщения в массиве. Просто запишите массив в поток объекта и прочитайте массив на стороне сервера.

Ваш "метод чтения с сервера" читает только один объект. Если он вызывается несколько раз, вы получите ошибку, так как он пытается открыть несколько потоков объектов из одного входного потока. Это не будет работать, так как все объекты были записаны в один и тот же поток объектов на стороне клиента, поэтому вы должны отразить это расположение на стороне сервера. То есть используйте один входной поток объектов и считайте из него несколько объектов.

(Ошибка, которую вы получаете, заключается в том, что objectOutputStream записывает заголовок, который ожидает objectIutputStream. Поскольку вы пишете не несколько потоков, а просто несколько объектов, то следующий объектInInStStream, созданный на входе сокета, не сможет найти второй заголовок и выдает исключение.)

Чтобы исправить это, создайте objectInputStream, когда вы принимаете соединение с сокетом. Передайте этот objectInputStream вашему методу чтения сервера и прочитайте Object из этого.

1 голос
/ 30 мая 2010

когда я отправляю только один объект с клиента на сервер, все работает хорошо.

когда я пытаюсь отправить несколько объектов один за другим в одном потоке, я получаю StreamCorruptedException.

На самом деле ваш клиентский код записывает один объект на сервер и читает несколько объектов с сервера.И на стороне сервера нет ничего, что записывает объекты, которые клиент пытается прочитать.

0 голосов
/ 10 мая 2012

Это исключение также может возникнуть, если вы используете Socket s на одной стороне и SSLSocket s на другой. Важна последовательность.

...