私は高性能サーバーを作成する方法についてソケットプログラミングと読書を見てきました。接続を受け入れた後にリスニング状態に戻すソケットを置くためにSocket
のAcceptAsync
方法を使用して、どのように時々呼び出しがsyncronously実行(およびfalseを返す)も接続がすぐに利用可能である場合に、どのように読んソケットリスナー複数同時AcceptAsync呼び出し
、私がし始めましたたとえ1000クライアントが一度に接続されていても、クライアントがどれくらい速くパススルーできるかによっては、最終的には1つの新しい接続を一度に処理するだけで、AcceptAsync
を使用する接続を受け入れるソケットは非同期的に「待機」します処理のための別のスレッドに、パフォーマンスを制限することがあります。
これは私が意図していたオブジェクトプールではなく、すべての接続にSocketAsyncEventArgs
という単一のインスタンスを使用して、このことを念頭に置いてクラスを作成できるかどうか疑問に思いました。
このことについてもっと考えてみると、接続が利用できない間に複数のAcceptAsync
コールが行われた場合に何が起こるのかと疑問に思った。だから私は何が起こるか見るために、この非常に非常にラフなテストアプリケーションを作っ:
class Program
{
private static Socket s;
static void Main(string[] args)
{
s = new Socket(IPAddress.Any.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
s.Bind(new IPEndPoint(IPAddress.Any, 10001));
s.Listen(10);
var e = new SocketAsyncEventArgs();
e.Completed += EOnCompleted;
s.AcceptAsync(e);
e = new SocketAsyncEventArgs();
e.Completed += EOnCompleted;
s.AcceptAsync(e);
e = new SocketAsyncEventArgs();
e.Completed += EOnCompleted;
s.AcceptAsync(e);
e = new SocketAsyncEventArgs();
e.Completed += EOnCompleted;
s.AcceptAsync(e);
while (true)
{
}
}
private static void EOnCompleted(object sender, SocketAsyncEventArgs socketAsyncEventArgs)
{
Console.WriteLine(socketAsyncEventArgs.AcceptSocket.RemoteEndPoint);
Thread.Sleep(10000);
var e = new SocketAsyncEventArgs();
e.Completed += EOnCompleted;
s.AcceptAsync(e);
}
}
私が接続してアプリケーションをスパムへのTCPテストアプリケーションを使用して、結果が複数のAcceptAsync
呼び出しは、複数の/受諾の完全なサイクルを作成したことを示しました。並行して実行されたようだ。
私の質問は、実際には何か利点がありますか?着信接続の処理を高速化するには正当な方法ですか?何か欠点はありますか?
EDIT 1:データを常に非同期呼び出し用に処理することができれば、それらはすべて同期的に実行され、新しい接続を受け入れることはできません。かなりの遅れがある。
高性能サーバーを実際に作成するにはどうすればよいですか。
ありがとう、これは非常に有用です、インターネットは、答えを氾濫させ、それを行うためのあらゆる方法が最良の方法である方法についての10ページの記事を流しています。私の唯一の関心事は、長期実行タスクに 'Task'を使用するのが適切かどうかです。私のサーバーには何千もの接続が長時間オープンしています。私が各ソケットへの完全な同期アクセスを使用した場合、それは私が意味することですが、何千ものタスクが常に実行されています。それは受け入れられますか? – Ashigore
これは、awaitを使用した非同期ソケットIOの素晴らしいケースです。あなたは1000sの接続をそうすることができます(スレッドを消費するわけではありません)。しかし、acceptループはちょうど1スレッドです。誰も気にしない。通常は同期IOである、あなたにとって便利なことをしてください。 – usr
したがって、async IOと待機を使用してRunConnectionAsyncを実装します。 acceptループは、この答えに立っているので正しいです。 – usr