我对为什么我的Socket.BeginSendFile 一次只异步发送两个文件感到困惑。我已经在不同的计算机上进行了测试,结果相同。
Socket.BeginSend似乎按预期一次发送所有三个。
我测试了将三个客户端连接到服务器。效果很好,所有三个都按预期异步连接。每个客户端(图片中的 Test100.exe、Test200.exe、Test300.exe)将根据连接的客户端从服务器请求名为 100、200 或 300 的文件夹中的文件。
问题是Socket.BeginSendFile一次最多只能将两个文件发送到流中。一旦之前调用的 2 个Socket.BeginSendFile 之一完成。见下文;
前两个发送的客户端之一完成发送后,第三个开始接收。
在代码中放置一些断点,我可以看出所有三个 Socket.BeginSendFile(...) 都被称为异步。
private static void Send(Socket handler, String data)
{
string dateFolder = data.Replace("<EOF>", "");
string longFileName = "C:\\"+dateFolder+"\\poopoo.txt";
string shortFileName = "poopoo.txt";
// ==== for beginSend
//byte[] fileData = File.ReadAllBytes(longFileName);
// ==== for beginSend
byte[] fileNameByte = Encoding.ASCII.GetBytes(shortFileName);
byte[] fileInfo = Encoding.ASCII.GetBytes("C:\\Users\\Trim\\Desktop");
byte[] fileInfoLen = BitConverter.GetBytes(fileInfo.Length); // we know these are ints (4bytes)
byte[] clientData = new byte[4 + fileNameByte.Length + fileInfoLen.Length + fileInfo.Length];// + fileData.Length + eofByte.Length
// ==== for beginSend
//byte[] clientData = new byte[4 + fileNameByte.Length + fileInfoLen.Length + fileInfo.Length + fileData.Length];
// ==== for beginSend
byte[] fileNameLen = BitConverter.GetBytes(fileNameByte.Length); // we know these are int (4bytes);
fileNameLen.CopyTo(clientData, 0);
fileNameByte.CopyTo(clientData, 4); // room for error file name 4bytes?
fileInfoLen.CopyTo(clientData, 4 + fileNameByte.Length);
fileInfo.CopyTo(clientData, 4 + fileNameByte.Length + fileInfoLen.Length);
// ==== for beginSend
//fileData.CopyTo(clientData, 4 + fileNameByte.Length + fileInfoLen.Length + fileInfo.Length);
// ==== for beginSend
// *** Break point shows all three being called async
handler.BeginSendFile(longFileName, clientData, null, 0, new AsyncCallback(AsynchronousFileSendCallback), handler);
// handler.BeginSend(clientData, 0, clientData.Length, 0, new AsyncCallback(SendCallback), handler);
}
第三个 Socket.BeginSendFile(...) 实际上直到前两个 AsynchronousFileSendCallback 方法之一才开始发送文件
private static void AsynchronousFileSendCallback(IAsyncResult ar)
{
// Retrieve the socket from the state object.
Socket client = (Socket)ar.AsyncState;
// Complete sending the data to the remote device.
client.EndSendFile(ar); // **Third** client doesn't actually start receiving his data until EndSendFile is called atleast once.
Console.WriteLine("Send file to client.");
// sendDone.Set();
client.Shutdown(SocketShutdown.Both);
client.Close();
}
正如我之前所说,如果我使用Socket.BeginSend,问题就会消失。虽然我需要能够使用Socket.BeginSendFile因为它将文件分块在一个单独的线程上,特别是byte[] fileData = File.ReadAllBytes(longFileName);
与我的Socket.BeginSend结构一起使用的这行代码对于大文件来说是不可接受的:(
非常感谢大家的时间!