通过TCP C#

时间:2016-04-01 22:31:46

标签: c# winforms serialization tcp treeview

这听起来很复杂,但我在计算机上有一个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 handler,__BinaryParser serParser,Boolean fCheck,Boolean isCrossAppDomain,IMethodCallMessage methodCallMessage) 在System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream,HeaderHandler handler,Boolean fCheck,Boolean isCrossAppDomain,IMethodCallMessage methodCallMessage) 在System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream)

对于长篇帖子感到抱歉,感谢您阅读,任何想法都是适当的

1 个答案:

答案 0 :(得分:1)

阅读循环有一个问题:

If(Page.IsPostBack) Then Exit Sub

Page_Load的第二个参数是缓冲区偏移量。由于您传递0(零),因此每次读取调用基本上都会覆盖前一次,从而最终导致数据不正确。这也解释了为什么它适用于小数据 - 因为如果一次读取它,一切都很好。

正确的方法是将while (bytesReceived < data.Length) { bytesReceived += stream.Read(data, 0, data.Length - bytesReceived); } 作为偏移量传递:

Stream.Read