【问题标题】:TCP File Transfer - Few bytes errorTCP 文件传输 - 几个字节错误
【发布时间】:2014-05-17 20:03:43
【问题描述】:

我目前正在开发一个 C# 程序,该程序允许用户通过网络发送文件并在另一端重新组装它。除了一些字节被错误地放置在目标中之外,一切都运行良好,使其与开始时的文件不完全相同。 (例如破坏图像)。 编辑:至少当它在我的计算机上时,我注意到可以通过让客户端在开始从流中读取之前等待一秒钟来解决该错误,这让我认为客户端偶尔会到达流的末尾并读取取而代之的是别的东西。知道如何以更好的方式解决这个问题,而不是像其他计算机那样等待一秒钟,我不知道这是否可行。 我的服务器代码如下:

TcpListener listener = new TcpListener(13);
        listener.Start();
        FileStream inputStream = File.OpenRead(loadLocation.Text);//loadLocation being a text box with the file path
        FileInfo f = new FileInfo(loadLocation.Text);
        int size = unchecked((int)f.Length);//Get's the file size in Bytes
        int  csize = size / 4096;//Get's the size in chunks of 4kb;

           statusLabel.Text = "Waiting for connection...";
            TcpClient client = listener.AcceptTcpClient();
            statusLabel.Text = "Connection accepted.";
            NetworkStream ns = client.GetStream();
            byte[] byteSize = BitConverter.GetBytes(size);//Sends the number of bytes to expect over the network
            try
            {
                ns.Write(byteSize, 0, byteSize.Length);
                byte[] temp = new byte[4096];
                for (int i = 0; i < csize; i++)
                {
                    inputStream.Read(temp, 0, 4096);
                    ns.Write(temp, 0, 4096);
                }
                byte[] end = new byte[size % 4096];
                inputStream.Read(end, 0, size % 4096);
                ns.Write(end, 0, size % 4096);
                ns.Close();
                inputStream.Close();
                client.Close();
                done = true;
                statusLabel.Text = "DONE!";
            }
            catch (Exception a)
            {
                Console.WriteLine(a.ToString());
            }
        listener.Stop();

客户端代码如下:

try
        {
            FileStream outputStream = File.OpenWrite(saveLocation.Text);
            TcpClient client = new TcpClient("127.0.0.1", 13);

            NetworkStream ns = client.GetStream();

            byte[] byteTime = new byte[sizeof(int)];
            int bytesRead = ns.Read(byteTime, 0, sizeof(int));
            int size;
            size = BitConverter.ToInt32(byteTime, 0);
            int csize = size / 4096;
            byte[] temp = new byte[4096];
            for (int i = 0; i < csize; i++)
            {
                ns.Read(temp, 0, 4096);
                outputStream.Write(temp, 0, 4096);
            }
            byte[] end = new byte[size % 4096];
            ns.Read(end, 0, size % 4096);
            outputStream.Write(end, 0, size % 4096);
            ns.Close();
            outputStream.Close();
            client.Close();
            statusLabel.Text = "DONE!";

        }
        catch (Exception a)
        {
            Console.WriteLine(a.ToString());
        }

我知道 TCP 保证交付顺序,因此我不知道是什么可能导致输出文件出现问题。另一个值得注意的部分是每次损坏都略有不同,例如在传输图像时,图像上的不同点会有一个大标记。

【问题讨论】:

    标签: c# .net tcp


    【解决方案1】:

    您的代码应该考虑到,NetworkStream(通常是大多数TCP sockets)不一定返回最初请求的全部字节数。

    微软writes:

    读取操作读取尽可能多的数据,直到 size 参数指定的字节数。

    在您的读取操作周围添加一个外部循环,以确保实际填充缓冲区。还建议进行更多的错误处理。

    也许,您可以从类似的question+answer 中获得一些灵感。它显示了这样一个外部循环的样子。

    【讨论】:

    • 非常感谢,如果我有更多的声誉,我会投票给你的答案。
    猜你喜欢
    • 2012-01-12
    • 1970-01-01
    • 1970-01-01
    • 2023-03-08
    • 2014-06-21
    • 2018-05-14
    • 1970-01-01
    • 1970-01-01
    • 2012-07-12
    相关资源
    最近更新 更多