0

C# で記述されたマルチスレッド TCP サーバーがあります。クライアントはサーバーによって受け入れられ、接続されているときにサーバーを離れません。約 1300 のアクティブな接続の後、ソフトウェアで System.OutOfMemmoryException エラーが発生します。この問題は 32 ビット システム アーキテクチャと RAM に関連していますか? 私は 32 ビットの Windows 7 Professional と 4 GB の RAM を持っています。サーバーに約 1300 のアクティブな接続が存在する場合、メモリ使用量は約 2.1GB で、CPU 使用率は 30% です。

ありがとうございました。

4

3 に答える 3

5

System.OutOfMemmoryExceptionプロセスで ~1300 のスレッドが作成されるとスローされます (32 ビット OS)。問題は、接続ごとに新しいスレッドを作成していることです。それは悪い習慣です。

代わりに、送信データの管理には 1 つのスレッドのみを使用し、送信には同じスレッド (または 2 番目のスレッド) を使用し、接続の受け入れには 1つのスレッドのみを使用する必要があります。

すべてのクライアントを受け入れるスレッド プールのコード例:

TcpListener tcpListener = new TcpListener(IPAddress.Any, 90);

public void BeginAccept()
{
    try { tcpListener.BeginAcceptTcpClient(AcceptClient, null); }
    catch { /* Swallowing is bad */ }
}

private void AcceptClient(IAsyncResult ar)
{
    TcpClient tcpClient;

    try { tcpClient = tcpListener.EndAcceptTcpClient(ar); }
    catch { /* Swallowing is bad */ }
    finally { BeginAccept(); }

    // TODO: Add your brand new tcpClient to some sort of collection, may be.
}

すべてのクライアントを受け入れる 1 つのスレッドのコード例:

TcpListener tcpListener = new TcpListener(IPAddress.Any, 90);
bool isListening;

public void BeginAccept()
{
    while (isListening)
    {
        TcpClient tcpClient;

        try { tcpClient = tcpListener.AcceptTcpClient(); }
        catch { /* Swallowing is bad */ }

        // TODO: Add your brand new tcpClient to some sort of collection, may be.
    }
}
于 2012-04-12T12:08:01.177 に答える
0

Asynchronous Server Socketの実装を検討する必要があります。
キュー/TCP の再送信を避けるために、別のスレッドで応答を送信することをお勧めします。
タスクを使用するか、受信したメッセージを関連する接続と共に並行キューに追加し、作業クルーがそれらを処理することができます。

于 2012-04-12T12:20:27.123 に答える
0

お使いのコンピューター/OS は制限要因ではありません。プロセスごとに約 4GB を割り当てることができます (合計で 4GB 以上を使用すると、ディスクへのスワップ/書き込みが開始されます。これは通常のメモリよりもはるかに遅くなりますが、それでも機能します)。ただし、C# コンパイラによって制限されます。C# はデフォルトで 32 ビット用にコンパイルされます。これは、各プロセスが約 2GB のメモリしか使用できないことを意味します。これが、2GB に達するとサーバーがクラッシュする理由です。事実上無制限のメモリを使用できる64ビットOS用にコンパイルできますが、64ビットOSがないため、マシンでは実行されません。

スレッドではなく、クライアント接続ごとに新しいプロセスを作成することをお勧めします。メイン プロセスは接続をリッスンして受け入れ、新しい接続が確立されると、そのクライアントとの接続の処理専用の新しいプロセスを生成する必要があります。各接続には独自のプロセスがあるため、2 GB の制限に達することはなく、さらに多くの利点があります。接続が閉じられると、メモリの再利用がはるかに簡単になり、1 つの接続でエラーが発生してもプログラム全体がクラッシュする可能性が低くなります。もちろん、共有メモリがないため、マルチプロセス アーキテクチャのプログラミングはマルチスレッド アーキテクチャのプログラミングよりも多少難しくなりますが、ここではより良いアプローチです。

于 2012-04-12T12:21:26.003 に答える