1

我目前正在使用套接字尝试在 Silverlight 3 客户端和 .NET3.5 服务之间发送消息。我可以很好地设置 TCP 连接,并发送数据,但我的问题在于序列化和反序列化 DataContracts。

目前我们正在使用 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 等,但似乎没有任何效果。我检查了客户端和服务器端的 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 回答