这听起来有点复杂,但我在电脑上有一个树视图。然后我将其转换为一个字节数组,通过tcp发送,将字节数组转换回树视图,然后再次查看它。出于某种原因,它的车非常多,完全相同的树视图可能会工作一次,然后不是在未来10次。如果树视图较小,它的作用似乎更大。我知道一个事实,错误来自于通过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(二进制分析器输入)
在System.Runtime.Serialization.Formatters.Binary.\u BinaryParser.ReadSerializationHeaderRecord()上
在system.runtime.serialization.formatters.binary上运行。
在system.runtime.serialization.formatters.binary.objectReader.deserialize(headerhandler处理程序,u BinaryParserParser,Boolean Fcheck,Boolean IsCrossAppDomain,IMethodcallMessage methodCallMessage)
在System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(流序列化流、HeaderHandler处理程序、Boolean Fcheck、Boolean IsCrossAppDomain、IMethodCallMessage方法调用消息)
在System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(流序列化流)时
对这篇长文章感到抱歉,谢谢你的阅读,任何想法都是有价值的。

最佳答案

读取循环有一个问题:

while (bytesReceived < data.Length)
{
    bytesReceived += stream.Read(data, 0, data.Length - bytesReceived);
}

Stream.Read的第二个参数是缓冲区偏移量。由于您正在传递0(零),所以每个读取调用基本上都会覆盖前面的调用,从而以错误的数据结束。这也解释了为什么它可以处理小数据,因为如果它是一次读取,一切都很好。
正确的方法是将bytesReceived作为偏移传递:
while (bytesReceived < data.Length)
{
    bytesReceived += stream.Read(data, bytesReceived, data.Length - bytesReceived);
}

关于c# - 通过TCP C#发送字节[](TreeView),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/36366810/

10-11 15:17