繁体   English   中英

.NET,NetworkStream套接字中的TCP文件发送问题

[英]TCP File Send issue in .NET, NetworkStream Socket

我正在使用以下代码通过tcp发送文件。

如果我连续多次发送同一文件来测试其是否健壮,则我会正确接收第一个文件,而另一个文件会弄乱。

所有混乱的文件具有相同的不正确字节,并且如果我睡眠(一会儿),所有文件都将正确传输。 我注意到我在读取文件时必须实例化一个新的缓冲区,以使所有操作正确完成。 但是我不明白为什么。

我担心重新实例化缓冲区的解决方案可能只是隐藏了另一个主要问题。 有什么建议吗?

using(var fileStream = new FileStream(file, FileMode.Open, FileAccess.Read))
{
    using(var binaryReader = new BinaryReader(fileStream))
    {
        var _sendingBuffer = new byte[BUFFER_SIZE];

        int length = (int)fileStream.Length;
        int bytesRead = 0;

        //Ensure we reached the end of the stream regardless of encoding
        while (binaryReader.BaseStream.Position != binaryReader.BaseStream.Length)
        {
            bytesRead = binaryReader.Read( _sendingBuffer, 0, _sendingBuffer.Length);

            _socket.BeginSend(_sendingBuffer, 0, bytesRead, SocketFlags.None, SendFileCallback, null);

            //without this i received some messed up data
            _sendingBuffer = new byte[BUFFER_SIZE];
        }    
    }
}

BeginSend是一个异步操作。 它只能保证在您调用它后才能启动,不会立即完成。 只要套接字正在发送传递的数据,就不得对该数据进行更改。 操作结束将通过AsyncCallback回调参数发出信号。

您的问题恰恰是您在传输仍在进行时更改了传输缓冲区。 为每个传输调用创建一个新的数组可以解决此问题。

解决该问题的其他方法:

  • 使用阻塞的Socket.Send函数,该函数将阻塞直到发送完所有数据并且可以重用缓冲区为止。 这也将使您的错误处理更加容易,因为错误不会通过AsyncCallback
  • 使您的完整程序异步运行,例如使用C#5的异步任务和异步/等待功能,因此:
    1. 首先异步读取文件的一部分。
    2. 异步读取完成后,通过套接字异步发送
    3. 完成后,还有更多数据要读取,请返回1。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM