オブジェクトを使用して通信するクライアントサーバーアプリケーションがあります。
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
}
複数のオブジェクトを送信している場合、Object[]
またはList
。これにより、ストリームの終わりを明示的に確認する必要がなくなり、ストリーム内のオブジェクトの数を明示的に送信できます。
編集:コードをフォーマットしたので、すでにメッセージが配列にあることがわかります。単純に配列をオブジェクトストリームに書き込み、サーバー側で配列を読み取ります。
「サーバー読み取りメソッド」は1つのオブジェクトのみを読み取ります。複数回呼び出された場合、同じ入力ストリームから複数のオブジェクトストリームを開こうとしているため、エラーが発生します。すべてのオブジェクトはクライアント側でsameオブジェクトストリームに書き込まれているため、これは機能しません。したがって、サーバー側でこの配置をミラーリングする必要があります。つまり、1つのオブジェクト入力ストリームを使用して、そこから複数のオブジェクトを読み取ります。
(エラーは、objectOutputStreamがobjectIutputStreamが予期するヘッダーを書き込むためです。複数のストリームを書き込むのではなく、単に複数のオブジェクトを書き込むため、ソケット入力で作成された次のobjectInputStreamは2番目のヘッダーを見つけられず、スローします例外。)
修正するには、ソケット接続を受け入れるときにobjectInputStreamを作成します。このobjectInputStreamをサーバーのreadメソッドに渡し、そこからObjectを読み取ります。
1つのオブジェクトのみをクライアントからサーバーに送信すると、すべてうまくいきます。
同じストリームで複数のオブジェクトを次々に送信しようとすると、
StreamCorruptedException
が返されます。
実際、クライアントコードは1つのオブジェクトをサーバーに書き込み、読み取りサーバーから複数のオブジェクトを書き込みます。また、サーバー側にはwritingクライアントが読み取ろうとしているオブジェクトはありません。