-1

複雑なオブジェクトを両側に転送する非同期ソケット アプリケーションを作成しようとしています。

ここで例を使用しました...

マルチパッケージデータを送信しようとするまで、すべて問題ありません。転送されたデータに複数のパッケージが必要な場合、転送サーバー アプリケーションが中断され、サーバーがエラーなしで制御不能になっています...

何時間も後に解決策を見つけました。各 EndSend コールバックの後にクライアントの送信側ソケットを閉じると、問題は解決します。しかし、なぜこれが必要なのか理解できませんでしたか?または、状況に対する他の解決策はありますか?

私の(2)プロジェクトは上記の例と同じですが、 EndSend コールバック メソッドを次のように変更しただけです。

    public void EndSendCallback(IAsyncResult result)
    {
        Status status = (Status)result.AsyncState;
        int size = status.Socket.EndSend(result);
        status.Socket.Close(); // <--------------- This line solved the situation
        Console.Out.WriteLine("Send data: " + size + " bytes.");
        Console.ReadLine();
        allDone.Set(); 
    }

ありがとう..

4

1 に答える 1

0

これは、指定されたサンプル コードが複数のパッケージを処理しない (そして壊れている) ためです。

いくつかの観察:

  • サーバーは一度に 1 つのクライアントしか処理できません。
  • サーバーは、入ってくるデータが要求されたデータよりも小さい単一の読み取りであるかどうかを単純にチェックし、そうであれば、それが最後の部分であると想定します。
  • サーバーは、接続を開いたままにしている間、クライアント ソケットを無視します。これにより、クライアント側で接続を閉じる責任が生じ、混乱を招く可能性があり、サーバーのリソースを浪費します。

最初の観察は実装の詳細であり、あなたの場合にはあまり関係ありません。2 番目の観察結果は、原因不明のバグが発生する可能性が高いため (おそらく開発ではなく)、このコードが実際のシナリオのどこかで実際に実行されている場合に関連します。ソケットは合理化されていません。クライアントが 1000 バイトを超えて送信した場合。これには、サーバー上での読み取りに 1 回または 10 回の呼び出しが必要になる場合があります。read の呼び出しは、「何らかの」データが利用可能になるとすぐに戻ります。あなたがする必要があるのは、送信されるデータの量、またはすべてのデータが送信されたときのいずれかを通信する、ある種のプロトコルを実装することです。HTTP プロトコルは十分にテストされ、十分にサポートされており、ほとんどのシナリオに適合するプロトコルであるため、HTTP プロトコルを使用することを強くお勧めします。

3 番目の観測は、すべての接続を開いたままにするため、サーバーのリソースが不足しているというバグを引き起こす可能性もあります。

于 2012-09-09T05:43:48.497 に答える