1

現在、ソケットを使用して、Silverlight 3 クライアントと .NET3.5 サービスの間でメッセージを送信しようとしています。TCP 接続を正常にセットアップしてデータを送信できますが、DataContract のシリアル化と逆シリアル化に問題があります。

現在、この作業を行うために WCF PollingDuplex バインディングを使用していますが、そのパフォーマンスに満足していないため、DataContract 属性を利用しようとしながらソケットを試しています。私が持っているコードは次のとおりです。

// Client
public void Send(ActionMessage actionMessage)
{
        DataContractSerializer dcs =
            new DataContractSerializer(actionMessage.GetType());

        MemoryStream memoryStream = new MemoryStream();

        dcs.WriteObject(memoryStream, actionMessage);

        byte[] sendBuffer = new byte[4096];
        memoryStream.Position = 0;
        memoryStream.Read(sendBuffer, 0, sendBuffer.Length);

        SocketAsyncEventArgs socketAsyncEventArgs = new SocketAsyncEventArgs();

        socketAsyncEventArgs.SetBuffer(sendBuffer, 0, sendBuffer.Length);

        if(!_socket.SendAsync(socketAsyncEventArgs))
            HandleSendComplete(socketAsyncEventArgs);
    }

// Service

private byte[] _recieveBuffer = new byte[4096];
private int _receivedLength;

private void socket_OnReceiveComplete(IAsyncResult asyncResult)
{
        _receivedLength += _tcpClient.Client.EndReceive(asyncResult);

        // See if there's more data that we need to grab
        if (_receivedLength < _recieveBuffer.Length)
        {
            // Need to grab more data so receive remaining data
            _tcpClient.Client.BeginReceive(_recieveBuffer, _receivedLength,
                _recieveBuffer.Length - _receivedLength, SocketFlags.None,
                new AsyncCallback(socket_OnReceiveComplete), null);

            return;
        }

        MemoryStream memoryStream = new MemoryStream();

        memoryStream.Position = 0;
        memoryStream.Write(_recieveBuffer, 0, _recieveBuffer.Length);

        DataContractSerializer dcs = new DataContractSerializer(typeof(ActionMessage));

        object o = dcs.ReadObject(memoryStream);

        ActionMessage actionMessage = (ActionMessage) o;
}

XmlException: Unexpected End of File をスローするのは ReadObject 行です。受信時にバイト配列 (_recieveBuffer) の末尾の 0 を切り捨てたり、最後に 0 を 1 つだけ残したりするなど、さまざまなことを試しましたが、何も機能していないようです。クライアント側とサーバー側の byte[] バッファーを確認しましたが、最初と最後で同じ値を持ち、同じ長さです。また、actionMessage.GetType() と typeof(ActionMessage) を DataContractSerializer のパラメーターとして使用してみましたが、違いはありません...

ここで何が欠けていますか: dataContractSerializer.Write() が dataContractSerializer.Read() によって生成された出力を受け入れないのはなぜですか?

これに当たるまでは良い一日を過ごしていました...同じ問題を抱えている別の男を見つけましたが、サービス側でmemoryStream.Position = 0を設定するという解決策が提供されました...

前もって感謝します。

4

1 に答える 1

0

推測しなければならない場合、あなたのmemoryStream.Position = 0; 行が間違った場所にあります。

バッファをストリームに書き込んだ後、ストリーム内の位置をリセットする必要があります。

于 2010-02-18T21:24:30.330 に答える