Socket.BeginSendFileが一度に2つのファイルしか非同期で送信しない理由に戸惑っています。別のコンピューターでテストしたところ、同じ結果になりました。
Socket.BeginSendは、期待どおりに3つすべてを一度に送信するようです。
3つのクライアントをサーバーに接続することをテストしました。これはうまく機能しますが、3つすべてが期待どおりに非同期に接続します。各クライアント(図のTest100.exe、Test200.exe、Test300.exe)は、接続しているクライアントに応じて、サーバーから100、200、または300という名前のフォルダーからファイルを要求します。
問題は、Socket.BeginSendFileが一度に最大2つのファイルのみをストリームに送信していることです。以前にSocket.BeginSendFileと呼ばれていた2つのうちの1つが終了するとすぐに。下記参照;
送信する最初の2つのクライアントの1つが送信を終了するとすぐに、3番目のクライアントが受信を開始します。
コードにいくつかのブレークポイントを設定すると、3つすべての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);
}
3番目のSocket.BeginSendFile(...)は、最初の2つの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を使用できるようにする必要がありますが、これはファイルを別のスレッドでチャンク化するためです。特に、 Socket.BeginSendbyte[] fileData = File.ReadAllBytes(longFileName);
構造で使用されるこのコード行は、大きなファイルでは受け入れられません:(
本当にありがとうございました!