I have server and client application and they are communicating over NetworkStream. On server I binary serialize an object and send it over NetworkStream, it is read on client and deserialized. But it throws and error: Binary stream '0' does not contain a valid BinaryHeader. Possible causes are invalid stream or object version change between serialization and deserialization. First I checked the length of NetworkStream and it is the same on server and client after sending the serialized object. Then I add a server reference to client and use Server.SaveData to be sure I have exactly the same class when deserializing.
我有服务器和客户端应用程序,他们正在通过NetworkStream进行通信。在服务器上,我二进制序列化一个对象并通过NetworkStream发送它,它在客户端读取并反序列化。但它抛出并出错:二进制流'0'不包含有效的BinaryHeader。可能的原因是序列化和反序列化之间的无效流或对象版本更改。首先,我检查了NetworkStream的长度,在发送序列化对象后,它在服务器和客户端上是相同的。然后我添加一个服务器引用到客户端并使用Server.SaveData以确保我在反序列化时具有完全相同的类。
Then I tried serializing and deserializing then same object on server and code below works perfectly.
然后我尝试序列化和反序列化服务器上的相同对象,下面的代码完美地工作。
stream.Read(buffer, 0, total);
network_stream.Write(buffer, 0, total);
network_stream.Read(buffer, 0, total);
stream.Position = 0;
stream.Write(buffer, 0, total);
SaveData savedata = (SaveData)formatter.Deserialize(stream);
Here's full code from server:
这是服务器的完整代码:
Stream stream = new MemoryStream();
IFormatter formatter = new BinaryFormatter();
current_state.saveData(map, red, blu);
formatter.Serialize(stream, current_state);
int total = (int)stream.Length;
byte[] buffer = new byte[total];
writer.WriteLine(total.ToString());
writer.Flush();
stream.Read(buffer, 0, total);
network_stream.Write(buffer, 0, total);
stream.Close();
And client side:
和客户方:
Stream stream = new MemoryStream();
IFormatter formatter = new BinaryFormatter();
while (reader.Peek() == '\0') { reader.Read(); } //solved the problem, idkw
int total = Convert.ToInt32(reader.ReadLine().ToString());
byte[] buffer = new byte[total];
network_stream.Read(buffer, 0, total);
stream.Position = 0;
stream.Write(buffer, 0, total);
stream.Position = 0;
Console.Write(stream.Length.ToString());
Server.SaveData current_state = (Server.SaveData)formatter.Deserialize(stream); //here is the problem
stream.Close();
1 个解决方案
#1
0
Why not serialize/deserialize the data directly to the NetworkStream
(without intermediate MemoryStream
)?
为什么不直接将数据序列化/反序列化到NetworkStream(没有中间MemoryStream)?
A little example.
一个小例子。
Assume, there is a data structure that the server and the client use to exchange with (in your case the data structure is current_state
).
假设有一个服务器和客户端用来交换的数据结构(在您的情况下,数据结构是current_state)。
[Serializable]
public class UserData : ISerializable
{
public string Text { get; private set; }
public int Number { get; private set; }
public UserData(string text, int number)
{
Text = text;
Number = number;
}
protected UserData(SerializationInfo info, StreamingContext context)
{
Text = info.GetString("Text");
Number = info.GetInt32("Number");
}
void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("Text", Text);
info.AddValue("Number", Number);
}
}
To send the data structure (from the client side, for example):
要发送数据结构(例如,从客户端):
using (var networkStream = tcpClient.GetStream())
{
var userData = new UserData("Hello.", 9);
var binaryFormatter = new BinaryFormatter();
binaryFormatter.Serialize(networkStream, userData);
}
To receive the data structure (server side, for example):
要接收数据结构(例如,服务器端):
var binaryFormatter = new BinaryFormatter();
using (var networkStream = tcpClient.GetStream())
{
while (networkStream.DataAvailable)
{
var receivedData = (UserData)binaryFormatter.Deserialize(networkStream);
}
}
#1
0
Why not serialize/deserialize the data directly to the NetworkStream
(without intermediate MemoryStream
)?
为什么不直接将数据序列化/反序列化到NetworkStream(没有中间MemoryStream)?
A little example.
一个小例子。
Assume, there is a data structure that the server and the client use to exchange with (in your case the data structure is current_state
).
假设有一个服务器和客户端用来交换的数据结构(在您的情况下,数据结构是current_state)。
[Serializable]
public class UserData : ISerializable
{
public string Text { get; private set; }
public int Number { get; private set; }
public UserData(string text, int number)
{
Text = text;
Number = number;
}
protected UserData(SerializationInfo info, StreamingContext context)
{
Text = info.GetString("Text");
Number = info.GetInt32("Number");
}
void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("Text", Text);
info.AddValue("Number", Number);
}
}
To send the data structure (from the client side, for example):
要发送数据结构(例如,从客户端):
using (var networkStream = tcpClient.GetStream())
{
var userData = new UserData("Hello.", 9);
var binaryFormatter = new BinaryFormatter();
binaryFormatter.Serialize(networkStream, userData);
}
To receive the data structure (server side, for example):
要接收数据结构(例如,服务器端):
var binaryFormatter = new BinaryFormatter();
using (var networkStream = tcpClient.GetStream())
{
while (networkStream.DataAvailable)
{
var receivedData = (UserData)binaryFormatter.Deserialize(networkStream);
}
}