まず、動機を説明するための背景を少し説明します。私は、ファイアウォールで保護された 2 つのクライアントが間接的に相互に通信できるようにする、非常に単純な select() ベースの TCP「ミラー プロキシ」に取り組んでいます。両方のクライアントがこのサーバーに接続し、両方のクライアントが接続されるとすぐに、クライアント A からサーバーに送信された TCP バイトはすべてクライアント B に転送され、その逆も同様です。
クライアント A がサーバーに接続し、クライアント B が接続する前にデータの送信を開始した場合、サーバーにはデータを置く場所がありません。大量の RAM を使用してしまう可能性があるため、RAM にバッファリングしたくありません。クライアントBが必要とする可能性があるため、データをドロップしたくありません。したがって、クライアント B も接続されるまで、クライアント A のソケットで select()-for-read-ready を実行しないという 3 番目のオプションを選択します。そうすれば、クライアント A はすべての準備が整うまでブロックするだけです。
それも多かれ少なかれ機能しますが、クライアント A のソケットで読み取り可能を選択しないことの副作用は、クライアント A がサーバーへの TCP 接続を閉じることを決定した場合、サーバーはその事実について通知されないことです - - 少なくとも、クライアント B がやって来て、サーバーが最終的にクライアント A のソケットで読み取り準備を選択し、保留中のデータを読み取り、ソケットクローズ通知 (つまり、recv() が 0 を返す) を取得するまでは。
クライアントAがTCP接続を閉じたとき、サーバーが(タイムリーに)知る方法があればいいのですが。これを知る方法はありますか?この場合、ポーリングは受け入れられます (たとえば、select() を 1 分に 1 回起動し、そのような関数が存在する場合は、すべてのソケットで IsSocketStillConnected(sock) を呼び出すことができます)。