0

このMSDN マガジン 2005 年 8 月の記事で、Daryn Kiely が TCP サーバーを構築する 3 つの方法を説明しています。

3 番目のモデルである非同期モデルは、私のニーズに最も適したモデルですが、その内部動作の詳細を理解するのに苦労しています。

質問 1 - 接続を受け入れるスレッドの数について

この例では、 を呼び出してサーバーを起動するとStart()、コードは接続を受け入れる 10 個の ThreadPools を作成します。

public void Start()
{
    SetupServerSocket();
    for (int i = 0; i < 10; i++)
        _serverSocket.BeginAccept(AsyncCallback(AcceptCallback), _serverSocket);
}

_serverSocket.BeginAccept1 つだけを使用できない理由と、10 という数字を使用する理由がわかりませんでした。

質問 2 – 約 0 バイトの受信

ではReceiveCallback()、0 バイトを受信すると、接続を閉じます。なんで?0 バイトを受信した場合、常にクライアントが接続を閉じたと見なされますか? ここで行ったテストでは、クライアントが接続を閉じると、SocketException でキャッチされる例外が発生します。ここで何か不足していますか?

質問 3 – BeginReceive を再度行う必要性について

何かがソケットで受信された後、BeginReceive に戻されます。なぜ受信を再開する必要があるのですか? これは自動的にすべきではありませんか?

質問 4 – バッファ サイズについて

255 バイトのバッファが使用されます。メッセージの長さがバッファ サイズよりも大きい場合、複数の受信で断片化されることを理解しています。メッセージが断片化されないことを保証するのに十分な大きさのバッファ サイズを設定する必要がありますか、それともメッセージの断片化を処理するコードを提供する必要がありますか (複数の受信を 1 つのバッファに結合するため)。

4

2 に答える 2

3

質問1-接続を受け入れるスレッドの数について

この例では、Start()を呼び出してサーバーを起動すると、コードは接続を受け入れる10個のThreadPoolを作成します。

public void Start()
{
    SetupServerSocket();
    for (int i = 0; i < 10; i++)
        _serverSocket.BeginAccept(AsyncCallback(AcceptCallback), _serverSocket);
}

_serverSocket.BeginAcceptを1つだけ使用できない理由と、その数が10である理由がわかりませんでした。

そのようなものをいくつかスポーンする理由はありませんBeginAccept。代わりに、でnewBeginAcceptを呼び出すだけです。AcceptCallback

質問2–受信した約0バイト

ReceiveCallback()で、ゼロバイトを受信した場合、接続を閉じます。なんで?ゼロバイトが受信されたとき、クライアントは常に接続を閉じたと見なされますか?ここで行ったテストでは、クライアントが接続を閉じると、SocketExceptionでキャッチされる例外が発生します。ここで何かが足りませんか?

はい。0バイトは、正常な切断を意味します。つまり、反対側は最初に使用しShutdown、次にClose直接閉じる代わりに使用します。

その他の種類の切断では、例外が生成されます。

質問3–BeginReceiveを再度実行する必要性について

ソケットで何かが受信された後、BeginReceiveに戻されます。なぜ再び受信を開始する必要があるのですか?これは自動的に行われるべきではありませんか?

いいえ。たとえば、サーバーを閉じているときに、もう一度読みたくない場合があります。他のクライアントは、一度だけ受信し、データを処理してから切断したい場合があります。

質問4–バッファサイズについて

255バイトのバッファが使用されます。メッセージの長さがバッファサイズよりも長い場合、複数の受信で断片化されることを理解しています。メッセージが断片化されないことを保証するのに十分な大きさのバッファサイズを設定する必要がありますか、それともメッセージの断片化を処理するコードを提供する必要があります(単一のバッファで複数の受信を結合するため)?

1つの送信byte[]は、常に複数の受信に分割できます。1つの受信に2つの送信byte[]済みバッファを含めることもできます。これがTCPの仕組みです。

通常、1つの受信バッファを使用してから、別の受信バッファを使用してメッセージを作成します。offsetまたは、より大きなバッファーを使用し、メソッド呼び出しでより大きなバッファーを使用してメッセージを完了するようにReceiveに指示します

于 2012-11-06T13:40:55.897 に答える
2

よし、やってみる:

1) シングルは、サーバー ソケットが で次のものが呼び出されるBeginAcceptまで接続を受け入れないことを意味します。これは、すぐに呼び出されるのではなく、いくつかの作業が完了した後に呼び出されます。10という数字は任意だと思います.10をスプーリングするようなもので、本質的には最大10個の着信接続要求を同時に受け入れることができます. 多くのクライアントを処理する必要がない場合は、1 つでも機能すると思います。BeginAcceptAcceptCallbackBeginAccept

2)どのクライアントを使用したかわかりませんが、ブラウザとのソケット接続を使用しました。接続を閉じると、セグメントを送信して空にするのが好きです(または、とにかくデバッグしているものです)。閉鎖。これが正しくない場合は、誰かが私を修正できますが、それを確認することをお勧めします。

3)まあ、それは自動ではありません。そして、何かを見逃さないようにループするのは良いことです。

4) 私が知る限り、管理者が指定しない限り、Windows には TCP バッファ サイズの最大値がありません。したがって、おそらくそれを増やすことができますが、おそらく見てください:ソケットプログラミングに適したバッファーサイズは? -結局、ストリーミングプロトコルであるため、1回の受信ですべてのメッセージを取得しようとするべきではないとコメントに記載されています。

于 2012-11-06T13:33:48.247 に答える