2

最後のパケットからのACKが受信されるまで、Winsockのsend()関数がブロックされることを読みました。今、私はターン制のロールプレイングゲームのためにサーバーで遊んでいます。すべてが1つのスレッドで処理されます(64ソケットの場合)。要求が受信され、処理され、応答がソケットに書き込まれます。このプロセスを中断することはできません。

この方法で、たとえば1000クライアント(64ソケットごとに1つのスレッド)を処理することは可能ですか?

send()の完了に時間がかかりすぎたり、クライアントが悪意を持ってACKを送信しなかったり、接続が中断されたりした場合、サーバー全体がブロックされませんか?

ネットワークとリクエスト処理のロジックを2つのスレッドに分割しますか?その場合、ネットワーク転送を処理するスレッドは、send()またはrecv()によってブロックされる可能性があります。

それとも、オーバーラップしたI / Oを使用するのが最善でしょうか?

4

2 に答える 2

3

send()ソケットがブロッキングモードで実行されており、ソケットのアウトバウンドバッファがキューに入れられたデータでいっぱいになった場合にのみブロックします。同じスレッドで複数のソケットを管理している場合は、ブロッキングモードを使用しないでください。1つのレシーバーがタイムリーにデータを読み取らない場合、そのスレッドのすべての接続が影響を受ける可能性があります。代わりに非ブロッキングモードを使用するsend()と、ソケットがブロッキングが発生する状態になったことを報告し、次を使用できます。select()ソケットが新しいデータを再び受け入れることができる時期を検出します。より良いオプションは、代わりにオーバーラップしたI/OまたはI/O完了ポートを使用することです。アウトバウンドデータをOSに送信し、OSに待機中のすべてを処理させ、データが最終的に受け入れ/送信されたときに通知します。その通知を受け取るまで、特定のソケットの新しいデータを送信しないでください。多数の接続へのスケーラビリティを実現するには、通常、I/O完了ポートの方が適しています。

于 2012-10-17T21:34:10.190 に答える
0

いいえ、そのようには機能しません。次のMSDNドキュメントからsend

送信機能が正常に完了したからといって、データが正常に受信者に配信および受信されたことを示すものではありません。この関数は、データが正常に送信されたことを示すだけです。

于 2012-10-17T21:05:17.097 に答える