我试图将一些对象从服务器发送到客户端。 我的问题是,当我只发送1个对象时,一切正常。但是目前我添加了另一个对象,抛出异常 - “二进制流不包含有效的二进制头”或“没有对象的映射(随机数)”。 我的想法是,反序列化不了解流的开始/结束位置,我希望你们可以帮助我。
继承我的反序列化代码:
public void Listen()
{
try
{
bool offline = true;
Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal,
new Action(() => offline = Offline));
while (!offline)
{
TcpObject tcpObject = new TcpObject();
IFormatter formatter = new BinaryFormatter();
tcpObject = (TcpObject)formatter.Deserialize(serverStream);
if (tcpObject.Command == Command.Transfer)
{
SentAntenna sentAntenna = (SentAntenna)tcpObject.Object;
int idx = 0;
foreach (string name in SharedProperties.AntennaNames)
{
if (name == sentAntenna.Name)
break;
idx++;
}
if (idx < 9)
{
PointCollection pointCollection = new PointCollection();
foreach (Frequency f in sentAntenna.Frequencies)
pointCollection.Add(new Point(f.Channel, f.Intensity));
SharedProperties.AntennaPoints[idx] = pointCollection;
}
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message); // raise an event
}
}
序列化代码:
case Command.Transfer:
Console.WriteLine("Transfering");
Thread transfer = new Thread(new ThreadStart(delegate
{
try
{
string aName = tcpObject.Object.ToString();
int indx = 0;
foreach (string name in names)
{
if (name == aName)
break;
indx++;
}
if (indx < 9)
{
while (true) // need to kill when the father thread terminates
{
if (antennas[indx].Frequencies != null)
{
lock (antennas[indx].Frequencies)
{
TcpObject sendTcpObject = new TcpObject();
sendTcpObject.Command = Command.Transfer;
SentAntenna sa = new SentAntenna(antennas[indx].Frequencies, aName);
sendTcpObject.Object = sa;
formatter.Serialize(networkStream, sendTcpObject);
}
}
}
}
}
catch (Exception ex) { Console.WriteLine(ex); }
}));
transfer.Start();
break;
答案 0 :(得分:0)
有趣。您的序列化代码中没有什么特别奇怪的东西,我曾经看过人们过去使用vanilla concatenation处理多个对象,虽然我实际上总是建议不要这样,因为BinaryFormatter没有明确声明这种情况没问题。但是:如果不是,我唯一可以建议的是实施自己的框架;所以你的写代码变成:
读取的代码变为:
(在两种情况下都注意到在写入和读取之间将MemoryStream的位置设置为0)
如果你想在读取时避免使用缓冲区,你也可以实现一个封闭长度的Stream子类,这个位更复杂。
答案 1 :(得分:0)
显然我提出了一个非常简单的解决方案。我确保只允许一个线程同时传输数据,所以我更改了这行代码:
formatter.Serialize(networkStream, sendTcpObject);
到这些代码行:
if (!transfering) // making sure only 1 thread is transfering data
{
transfering = true;
formatter.Serialize(networkStream, sendTcpObject);
transfering = false;
}