我目前正在使用套接字尝试在 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 不起作用......
提前致谢。