1

一度に 1 つの接続を許可するように構成したサーバー ソケットがあります (セマフォで Accept 呼び出しをブロックすることにより)。バックログ キュー サイズは 1 です。つまり、.Listen(1) を呼び出しました。

次に、次のプロセスに従います。

  • サーバー ソケットで AcceptAsync を呼び出します (1 回だけ)
  • クライアントConnectAsyncがあります(正常に接続します)
  • 私はクライアントConnectAsyncを持っています(おそらくキューに接続されています...伝える方法がいいでしょう)
  • 3 番目のクライアント ConnectAsync があります

これら 3 つの ConnectAsync 呼び出しは、立て続けに発生します。

3 番目の ConnectAsync の予想される結果は、SocketAsyncEventArgs の "SocketError" プロパティが "SocketError.Success" 以外のものになることです。具体的には、「SocketError.ConnectionRefused」を実際に期待しています。

約 95% の確率で、これが当てはまります。3 番目のクライアントのコールバックは、Success 以外の SocketError 値を返します。

ただし、ときどき、3 番目の ConnectAsync が 2 番目の ConnectAsync と同じように "機能" します。EventArgs.SocketError は SocketError.Success を返し、対応する Socket.Connected プロパティは "true" を読み取ります。

どうしたの?AcceptAsync を1 回だけ呼び出します(ブレークポイントでこれを注意深く確認しました)。したがって、1 つのクライアントのみを受け入れ、残りはバックログ キューに入れる必要があります。私のキュー サイズは 1 ですが、3 番目のクライアントはどのように正常に接続していますか?

より大きなキュー サイズを使用するように言わないでください。これは、私が作成したテスト関数用であり、積極的にクライアントにサービスを提供しているコードではありません。この時点で、それはより好奇心です。:)

4

1 に答える 1

0

それはうまくいきません。システムは、リッスン バックログ 1 を独自の最小値 (少なくとも 50 になる) に引き上げます。

サーバーをシングルスレッドにするだけです。その後、一度に 1 つの接続のみを処理します。後続の接続は、バックログ キューで待機します。サーバーが Windows プラットフォームの場合、バックログ キューがいっぱいになると、「接続が拒否されました」というメッセージが表示されます。そうでなければ。

于 2011-01-10T23:30:10.283 に答える