将二进制格式化程序与异步套接字一起使用
Using Binary Formatter with asynchronous sockets
我正在尝试通过 serializing/deserializing 和 BinaryFormatter 利用 C# 中异步套接字的优势,但是 运行 遇到了几个问题。主要是,我不断收到错误消息:
No map for object 1953724755
尝试反序列化网络流时。
我已经尝试更改为同步套接字,这似乎工作正常,但是当使用异步套接字(使用 BeginRecieve 和 EndRecieve 等)时,我仍然会收到此错误。
这是我反序列化的代码:
private void BeginDictionaryRecieve(IAsyncResult ar)
{
Stream socketStream = new NetworkStream(socketState.workSocket);
IFormatter dataFormatter = new BinaryFormatter();
socketState.workSocket.EndReceive(ar);
List<string> rackthatWasClicked = (List<string>)
dataFormatter.Deserialize(socketStream);
this.recievedListForRackDisplay = rackthatWasClicked;
OnDataRecieved.Invoke();
socketState.workSocket.BeginReceive(socketState.buffer, 0, StateObject.BufferSize, 0,new AsyncCallback(BeginDictionaryRecieve), socketState);
}
这是序列化代码(同步):
IPAddress ipAdd = IPAddress.Parse("127.0.0.1");
TcpClient myClient = new TcpClient();
myClient.Connect(ipAdd, 8002);
Stream clientStream = myClient.GetStream();
IFormatter f = new BinaryFormatter();
f.Serialize(clientStream, ShelfDataToSend);
clientStream.Dispose();
myClient.Dispose();
我应该注意,我正在使用 BinaryFormatter,因为我似乎无法找到一种方法来序列化一个对象,而不是在一个套接字上使用正常的 .Write 操作。
感谢 Hans 的指导,我找到了一个很好的解决方案。我现在收到这样的数据:
try
{
StateObject state = (StateObject) ar.AsyncState;
Socket client = state.workSocket;
int bytesRead = client.EndReceive(ar);
if (bytesRead > 0)
{
stream.Write(state.buffer, 0, bytesRead);
client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(BeginDictionaryRecieve), state);
}
else
{
if (stream.Length > 1)
{
BinaryFormatter formatter = new BinaryFormatter();
stream.Position = 0;
this.recievedListForRackDisplay =(List<string>)formatter.Deserialize(stream);
OnDataRecieved.Invoke();
client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback(BeginDictionaryRecieve), state);
}
}
}
catch (Exception e)
{
throw e;
}
还应注意,此解决方案仅在客户端 Socket 在发送数据后被销毁时才有效。
我正在尝试通过 serializing/deserializing 和 BinaryFormatter 利用 C# 中异步套接字的优势,但是 运行 遇到了几个问题。主要是,我不断收到错误消息:
No map for object 1953724755
尝试反序列化网络流时。
我已经尝试更改为同步套接字,这似乎工作正常,但是当使用异步套接字(使用 BeginRecieve 和 EndRecieve 等)时,我仍然会收到此错误。
这是我反序列化的代码:
private void BeginDictionaryRecieve(IAsyncResult ar)
{
Stream socketStream = new NetworkStream(socketState.workSocket);
IFormatter dataFormatter = new BinaryFormatter();
socketState.workSocket.EndReceive(ar);
List<string> rackthatWasClicked = (List<string>)
dataFormatter.Deserialize(socketStream);
this.recievedListForRackDisplay = rackthatWasClicked;
OnDataRecieved.Invoke();
socketState.workSocket.BeginReceive(socketState.buffer, 0, StateObject.BufferSize, 0,new AsyncCallback(BeginDictionaryRecieve), socketState);
}
这是序列化代码(同步):
IPAddress ipAdd = IPAddress.Parse("127.0.0.1");
TcpClient myClient = new TcpClient();
myClient.Connect(ipAdd, 8002);
Stream clientStream = myClient.GetStream();
IFormatter f = new BinaryFormatter();
f.Serialize(clientStream, ShelfDataToSend);
clientStream.Dispose();
myClient.Dispose();
我应该注意,我正在使用 BinaryFormatter,因为我似乎无法找到一种方法来序列化一个对象,而不是在一个套接字上使用正常的 .Write 操作。
感谢 Hans 的指导,我找到了一个很好的解决方案。我现在收到这样的数据:
try
{
StateObject state = (StateObject) ar.AsyncState;
Socket client = state.workSocket;
int bytesRead = client.EndReceive(ar);
if (bytesRead > 0)
{
stream.Write(state.buffer, 0, bytesRead);
client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(BeginDictionaryRecieve), state);
}
else
{
if (stream.Length > 1)
{
BinaryFormatter formatter = new BinaryFormatter();
stream.Position = 0;
this.recievedListForRackDisplay =(List<string>)formatter.Deserialize(stream);
OnDataRecieved.Invoke();
client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback(BeginDictionaryRecieve), state);
}
}
}
catch (Exception e)
{
throw e;
}
还应注意,此解决方案仅在客户端 Socket 在发送数据后被销毁时才有效。