ネットワークファイル転送に関する問題があります。 2つ以上のクライアントが存在する場合、ソケットTCP/UDPのアップロードがネイティブウィンドウのコピーより遅くなります。ソケットファイル転送がWindowsコピーよりも遅いのはなぜですか?
私は1Gbpsのネットワークを持ついくつかのPCを持っています。
ここにWindowsのコピーケースがあります。
サーバーからの1つのクライアントコピーでは、最大アップロード速度は約100mbpsです。 (100mbpsを超えると、経路にボトルネックが発生する)
2人のクライアントがサーバーからコピーすると、最大アップロード速度は約200mbpsになります。
3台のクライアントがサーバーからコピーした場合、最大アップロード速度は約300mbpsです。
ここにソケットケースがあります。
サーバーからのクライアントのダウンロードでは、最大アップロード速度は約100mbpsです。
2人のクライアントがサーバーからダウンロードすると、最大アップロード速度は約100mbpsです。
3人のクライアントがサーバーからダウンロードした場合、最大アップロード速度は約100mbpsです。
ご覧のとおり、クライアント数が増えても、ソケットサーバーのアップロード速度は向上しません。
この問題をテストする簡単なプログラムを作成しました。同じ問題が発生します。 非常に簡単なsendとrecvの呼び出しです。 コードを確認してください。
class Program
{
static List<TcpClient> sessions = new List<TcpClient>();
static void Main(string[] args)
{
bool isServer = false;
Console.WriteLine("Run as a server? (Y/N)");
string answer = Console.ReadLine();
if (answer.ToUpper().StartsWith("Y")) isServer = true;
if (isServer)
{
TcpListener listener = new TcpListener(IPAddress.Any, 13579);
Console.WriteLine("Listening at: " + ((IPEndPoint)listener.LocalEndpoint).ToString());
listener.Start();
Thread workerThread = new Thread(() =>
{
while (true)
{
lock (sessions)
{
foreach (var client in sessions)
{
if (client.Available > 0)
{
byte[] buffer = new byte[client.Available];
int length = client.Client.Receive(buffer);
string filePath = Encoding.UTF8.GetString(buffer, 0, length);
if (File.Exists(filePath))
{
foreach (var receiver in sessions)
receiver.Client.SendFile(filePath, null, null, TransmitFileOptions.UseKernelApc | TransmitFileOptions.WriteBehind);
}
}
}
}
Thread.Sleep(200);
}
});
workerThread.IsBackground = true;
workerThread.Start();
while (true)
{
TcpClient client = listener.AcceptTcpClient();
lock (sessions)
{
sessions.Add(client);
}
}
}
else
{
Console.WriteLine("Enter the server IP:");
string ipAddress = Console.ReadLine();
TcpClient client = new TcpClient(ipAddress, 13579);
Console.WriteLine("Enter the file path on remote server:");
string remoteFilePath = Console.ReadLine();
if(remoteFilePath != "")
client.Client.Send(Encoding.UTF8.GetBytes(remoteFilePath));
byte[] recvBuffer = new byte[32768];
while(true)
{
try
{
client.Client.Receive(recvBuffer, 32768, SocketFlags.None);
}
catch (SocketException e)
{
Console.WriteLine("Transfer interrupted: {0}", e.Message);
break;
}
}
}
}
}
これにより、パフォーマンスの向上したソケットツールの実装が妨げられています。 希望のstackoverflowの人は私たちを助けることができます。 ありがとうございました。
は、クライアント/サーバの実装に依存サーバー(
BeginRead
/EndRead
)で非同期メソッドに切り替える必要があります。したがって、質問は答えが不可能です。 – jgauffinありがとうございました。 – OliverWho
Windowsコピーでテストする場合と同じマシンでコードを実行していますか? – nos