0

こんにちは,Netty を使用するサーバーを開発しています。目標は、オブジェクトを前後に送信できるようにすることです。そのため、ObjectDecoderInputStream と ObjectEncoderOutputStream を使用してサーバーを構成しました。

そのため、Nettyを使用してサーバーと通信するクライアントもあります。クライアントはうまく機能します。

Javaのソケットを使用して、サーバーからシリアライズ可能なオブジェクトを受け取るたびに。何か奇妙なことが起こりました。以下に例外があります。

java.io.StreamCorruptedException: Unsupported version: 0
at org.jboss.netty.handler.codec.serialization.CompactObjectInputStream.readStreamHeader(CompactObjectInputStream.java:38)
at java.io.ObjectInputStream.<init>(Unknown Source)
at org.jboss.netty.handler.codec.serialization.CompactObjectInputStream.<init>(CompactObjectInputStream.java:30)
at org.jboss.netty.handler.codec.serialization.ObjectDecoderInputStream.readObject(ObjectDecoderInputStream.java:115)
at com.bvd.main.Client.readResponse(Client.java:139)
at com.bvd.main.Client.getFile(Client.java:80)
at com.bvd.main.Client.main(Client.java:163)

クライアントからのオブジェクトの送信:

    public static void writeRequest(Message requestMsg,
        OutputStream outputStream) {
    byte[] bytes = null;
    ByteArrayOutputStream byteOutputStream = new ByteArrayOutputStream();
    try {
        ObjectEncoderOutputStream objectOutputStream = new ObjectEncoderOutputStream(
                byteOutputStream, 8192);
        objectOutputStream.writeObject(requestMsg);
        objectOutputStream.flush();
        bytes = byteOutputStream.toByteArray();
        byteOutputStream.close();
        objectOutputStream.close();
        outputStream.write(bytes);
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

クライアントがオブジェクトを受け取ったコード:

    public static Object readResponse(InputStream inputStream) {
    int count = 0;
    Object object = null;
    try {
        byte[] lenBuffer = new byte[4];
        while ((count = inputStream.read(lenBuffer)) < 4) {
        }
        System.out.println(ByteBuffer.wrap(lenBuffer).getInt());
        int infolen = ByteBuffer.wrap(lenBuffer).getInt();
        byte[] objBuffer = new byte[infolen];
        while ((count = inputStream.read(objBuffer)) < infolen) {
        }
        byte[] totalBuf = new byte[4 + infolen];
        System.arraycopy(lenBuffer, 0, totalBuf, 0, lenBuffer.length);
        System.arraycopy(objBuffer, 0, totalBuf, lenBuffer.length,
                objBuffer.length);

        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(
                totalBuf);
        System.out.println(byteArrayInputStream.available());
        ObjectDecoderInputStream objectDecoderInputStream = new ObjectDecoderInputStream(
                new BufferedInputStream(byteArrayInputStream));
        object = objectDecoderInputStream.readObject();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (ClassNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return object;
}

さらに混乱するのは、サーバー上で送信されるオブジェクトのコンテンツの長さ (オブジェクトは、バイト [] に変換されたファイルの一部を運ぶ) を 2858 (バイト) に設定すると、上記のクライアントはうまく機能します。長さを 2859 以上に変更すると、上記のStreamCorruptedExceptionが発生します。

ps: オブジェクトの送信は正常に機能し、サーバーは正常に受信され、正しくデコードされます。すべての質問は、サーバーから受信するオブジェクトに関するものです。

私の貧弱な英語で申し訳ありませんが、助けていただければ幸いです。ありがとう。

4

1 に答える 1

0

両方の読み取りループで、複数の読み取り呼び出しを行うと、偽のデータが取得されます。

    while ((count = inputStream.read(lenBuffer)) < 4) {
    }


    while ((count = inputStream.read(objBuffer)) < infolen) {
    }

read を呼び出すたびに、 の先頭にbyte[]書き込みます。したがって、ループするたびに、バッファー内のデータの一部を上書きし、バッファー全体のデータを読み取ることはありません。(これまでに読み取ったデータの量に基づいて)現在のオフセットを追跡し、それをスレッドread()呼び出しに渡す必要があります。また、割り当てではなく、カウントするために累積する必要があります。

于 2012-07-23T02:43:37.077 に答える