【问题标题】:how to fix file transfer , received files is corrupted?如何修复文件传输,收到的文件损坏?
【发布时间】:2012-04-24 12:42:35
【问题描述】:

我有使用 tcp 套接字的文件传输应用程序 [服务器-客户端]。

当我发送一个文件时,它会成功,但是当我发送一个包含许多文件的文件夹时,接收到的文件会损坏,请注意,从客户端发送的文件和从服务器接收的文件都具有相同的大小(相同字节数)。

服务器:

private void ReceiveX(Socket client, string destPath, long size, int bufferSize)
    {
        using (Stream stream = File.Create(destPath))
        {
            byte[] buffer = new byte[bufferSize];
            long sum = 0;
            int count = 0;
            do
            {
                count = client.Receive(buffer, 0, buffer.Length, SocketFlags.None);
                stream.Write(buffer, 0, count);
                sum += count;
            } while (sum < size);
        }
    }

客户:

private void SendX(Socket socket, string filePath, long size, int bufferSize, DoWorkEventArgs e)
    {
        using (Stream stream = File.OpenRead(filePath))
        {
            byte[] buffer = new byte[bufferSize];
            long sum = 0;
            int count = 0;
            do
            {
                if (worker.CancellationPending)
                {
                    e.Cancel = true;
                    return;
                }
                count = stream.Read(buffer, 0, buffer.Length);
                socket.Send(buffer, 0, count, SocketFlags.None);
                sum += count;
                worker.ReportProgress((int)((sum * 100) / size));
            } while (sum < size);
        }
    }

客户端和服务器的缓冲区大小都是 [4 * 1024]
上面的代码有什么问题吗?

客户端:这里我遍历文件夹以发送文件:

private void SendDir(string path, int bufferSize, DoWorkEventArgs e)
    {
        using (Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
        {
            IPEndPoint endpoint = new IPEndPoint(IPAddress.Any, 0);
            listener.Bind(endpoint);
            listener.Listen(1);
            client.ReceiveFolder((IPEndPoint)listener.LocalEndPoint, fileList, Path.Combine(currAddress,Path.GetFileName(path)),bufferSize);
            Socket socket = listener.Accept();
            int count = 0;
    foreach (_File file in fileList)
            {
                if (worker.CancellationPending)
                {
                    e.Cancel = true;
                    return;
                }
                Console.WriteLine(++count);
                SendX(socket, file.Path, file.Size, bufferSize, e);
            }
            socket.Dispose();
    }

服务器,遍历之前从服务器接收到的list&lt;_File&gt;中的文件,它包含客户端要发送的文件信息(名称、路径、大小):

 private void ReceiveFolderTh(IPEndPoint endpoint, List<_File> Files, string destDir, int bufferSize)
    {
        Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        client.Connect(IPAddress.Parse("127.0.0.1"), endpoint.Port);
        foreach (_File file in Files)
        {
            Directory.CreateDirectory(destDir  + Path.GetDirectoryName(file.Name));
            ReceiveX(client, destDir + file.Name, file.Size, bufferSize);
        }
        client.Dispose();
    }

那我该如何解决呢?

【问题讨论】:

    标签: c# sockets file-transfer corrupt-data


    【解决方案1】:

    问题很可能是您的客户端在第一个文件上接收到太多数据,因为您没有明确分隔文件。您的接收代码是:

    do
    {
        count = client.Receive(buffer, 0, buffer.Length, SocketFlags.None);
        stream.Write(buffer, 0, count);
        sum += count;
    } while (sum < size);
    

    您始终会收到最多 buffer.Length(您说是 4,096)字节。因此,如果第一个文件的长度为 100 字节,而下一个文件的长度为 5,000 字节,那么服务器很可能正在发送一个 4,096 字节的数据包,您的代码将尽职尽责地接收并存储在第一个文件中。

    您需要将调用中接收的字节数更改为client.Receive。比如:

    int bytesToReceive = Math.Min(buffer.Length, size - sum);
    count = client.Receive(buffer, 0, bytesToReceive, SocketFlags.None);
    

    这将阻止您从一个文件的末尾读取到下一个文件的开头。

    【讨论】:

    • 我已经这样解决了,客户端:try{ SendFile} finally { socket.Receive(new byte[1], SocketFlags.None); } 和服务器:try{ReceiveFile} finally { client.Send(new byte[1], SocketFlags.None); },所以客户端会等到服务器发送一个字节,但你的方式看起来更好!哪个更快?
    • 我的方法应该稍微快一点。
    猜你喜欢
    • 1970-01-01
    • 2020-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-27
    • 1970-01-01
    相关资源
    最近更新 更多