【发布时间】:2016-04-01 22:31:46
【问题描述】:
这听起来可能有点复杂,但我在计算机上有一个 TreeView。然后我将其转换为字节数组,通过 TCP 发送,将字节数组转换回树视图,然后再次查看。出于某种原因,它非常有问题,完全相同的树视图可能会工作一次,然后不会在接下来的 10 次。如果 TreeView 更小,它似乎工作得更多。我知道事实上错误是通过 tcp 发送的,因为我制作了一个程序,它只是将它转换为字节数组并返回,它在 100% 的时间里都可以工作。代码如下:
byte[] data = SerilizeQueryFilters(TreeFiles); //Convert to byte[] function, 100% works fine.
stream = client.GetStream();
int length = data.Length;
byte[] datalength = new byte[4];
datalength = BitConverter.GetBytes(length);
stream.Write(datalength, 0, 4);
stream.Write(data, 0, data.Length); //Sends the byte[]
这就是服务器发送给客户端的代码。在这一点上,我不确定我是否发送错误,所以接收错误,反之亦然。
接收字节数组的代码:
stream = client.GetStream();
new Thread(() =>
{
try
{
while ((i = stream.Read(datalength, 0, 4)) != 0)
{
byte[] data = new byte[BitConverter.ToInt32(datalength, 0)];
int bytesReceived = 0;
while (bytesReceived < data.Length)
{
bytesReceived += stream.Read(data, 0, data.Length - bytesReceived);
}
this.Invoke((MethodInvoker)delegate
{
try
{
if (CBCommand.SelectedItem.ToString() == "View Files")
{
DeSerilizeQueryFilters(data, TVFiles); //Convert the byte[] back into the tree view and view it
WriteToLog("Finished");
}
}
catch { }
});
}
}
catch { }
}).Start();
请记住,我还有其他用于接收图像的函数,以及使用完全相同代码的字符串,它们工作正常,所以我猜测它是因为它是一个树视图。将 byte[] 转换回 treeView 函数可以 100% 工作,但这就是它搞砸的地方(因为 byte[] 已损坏或未正确发送)将包含下面的代码
private void DeSerilizeQueryFilters(byte[] items, TreeView Treeview)
{
BinaryFormatter bf = new BinaryFormatter();
List<TreeNode> _list = new List<TreeNode>();
try
{
using (MemoryStream ms = new MemoryStream())
{
ms.Write(items, 0, items.Length);
ms.Position = 0;
_list = bf.Deserialize(ms) as List<TreeNode>;
Treeview.Nodes.AddRange(_list.ToArray());
}
}
catch (Exception ex) { WriteToLog("Error displaying files"); Console.WriteLine(ex); }
}
所以当它失败时,它会给我显示文件的消息错误并写下异常,以防万一:
System.Runtime.Serialization.SerializationException:输入流不是有效的二进制格式。起始内容(以字节为单位)为:6D-73-2E-54-72-65-65-4E-6F-64-65-02-00-00-00-1D-53 ...
在 System.Runtime.Serialization.Formatters.Binary.SerializationHeaderRecord.Read(__BinaryParser 输入)
在 System.Runtime.Serialization.Formatters.Binary.__BinaryParser.ReadSerializationHeaderRecord()
在 System.Runtime.Serialization.Formatters.Binary.__BinaryParser.Run()
在 System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize(HeaderHandler 处理程序,__BinaryParser serParser,布尔 fCheck,布尔 isCrossAppDomain,IMethodCallMessage methodCallMessage)
在 System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(流序列化流,HeaderHandler 处理程序,布尔 fCheck,布尔 isCrossAppDomain,IMethodCallMessage methodCallMessage)
在 System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream)
抱歉,帖子太长了,感谢阅读,任何想法都可以理解
【问题讨论】:
-
当您说 TreeView 时,您是指对象的层次结构,还是某种 UI 控件?
-
窗口形式的 TreeView 显示对象的层次结构
-
如果您想通过网络连接传输结构,我建议您创建 DTO。你在使用 WCF 吗?
-
我只是使用 Windows 窗体,我是编程的初学者,为此我只是希望只使用 Windows 窗体,因为所有其他功能都以相同的方式通过 tcp 传输。我希望这只是一个小修复,因为它唯一的树视图在图像/字符串所在的位置不起作用
-
不确定这是否是主要问题,但此代码
bytesReceived += stream.Read(data, 0, data.Length - bytesReceived);存在潜在问题。将其更改为bytesReceived += stream.Read(data, bytesReceived, data.Length - bytesReceived);
标签: c# winforms serialization tcp treeview