我正在使用以下代码通过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];
}
}
}
答案 0 :(得分:2)
BeginSend
是一个异步操作。它只会保证在你打电话后开始,它不会马上完成。只要套接字正在发送传递的数据,就不能改变该数据。
操作结束将通过AsyncCallback
回调参数发出信号。
您的问题正是您在传输仍在进行时突变了传输缓冲区。为每个传输调用创建一个新数组可以解决这个问题。
解决问题的其他方法:
Socket.Send
函数,该函数将阻塞,直到发送整个数据并且可以重用缓冲区。这也会使您的错误处理变得更加容易,因为错误不会显示在AsyncCallback
。