TCP文件传输 - 几个字节错误

时间:2014-05-17 10:54:26

标签: c# .net tcp

我目前正在开发一个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保证了交付顺序,因此我不知道可能导致输出文件出现问题的原因。另一个值得注意的部分是,每次腐败都略有不同,例如在传输图像时,图像上的不同点会有一个大的标记。

1 个答案:

答案 0 :(得分:1)

您的代码应该考虑到NetworkStream(一般来说大多数TCP sockets)不一定返回最初请求的完整字节数。

Microsoft writes

  

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

在读取操作周围添加外部循环以确保实际填充缓冲区。还有一些错误处理也是可取的。

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