web-dev-qa-db-ja.com

java.io.StreamCorruptedException:無効なストリームヘッダー:7371007E

オブジェクトを使用して通信するクライアントサーバーアプリケーションがあります。
1つのオブジェクトのみをクライアントからサーバーに送信すると、すべて正常に機能します。
複数のオブジェクトを同じストリームで次々に送信しようとすると、

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
}
20
Alex

複数のオブジェクトを送信している場合、Object[]またはList。これにより、ストリームの終わりを明示的に確認する必要がなくなり、ストリーム内のオブジェクトの数を明示的に送信できます。

編集:コードをフォーマットしたので、すでにメッセージが配列にあることがわかります。単純に配列をオブジェクトストリームに書き込み、サーバー側で配列を読み取ります。

「サーバー読み取りメソッド」は1つのオブジェクトのみを読み取ります。複数回呼び出された場合、同じ入力ストリームから複数のオブジェクトストリームを開こうとしているため、エラーが発生します。すべてのオブジェクトはクライアント側でsameオブジェクトストリームに書き込まれているため、これは機能しません。したがって、サーバー側でこの配置をミラーリングする必要があります。つまり、1つのオブジェクト入力ストリームを使用して、そこから複数のオブジェクトを読み取ります。

(エラーは、objectOutputStreamがobjectIutputStreamが予期するヘッダーを書き込むためです。複数のストリームを書き込むのではなく、単に複数のオブジェクトを書き込むため、ソケット入力で作成された次のobjectInputStreamは2番目のヘッダーを見つけられず、スローします例外。)

修正するには、ソケット接続を受け入れるときにobjectInputStreamを作成します。このobjectInputStreamをサーバーのreadメソッドに渡し、そこからObjectを読み取ります。

10
mdma

1つのオブジェクトのみをクライアントからサーバーに送信すると、すべてうまくいきます。

同じストリームで複数のオブジェクトを次々に送信しようとすると、StreamCorruptedExceptionが返されます。

実際、クライアントコードは1つのオブジェクトをサーバーに書き込み、読み取りサーバーから複数のオブジェクトを書き込みます。また、サーバー側にはwritingクライアントが読み取ろうとしているオブジェクトはありません。

1
Stephen C