Python epoll を使用するサーバーに接続されたクライアントのサブセットにメッセージを送信したいと考えています。fileno
接続されているクライアントのリストを取得する実用的な方法はありますか?
1 に答える
通常、これを処理する方法は、クライアントを自分で追跡することです。新しいクライアントを受け入れるたびに、 に追加する前にepoll
、コレクションにも追加してください。クライアントを削除するたびに、コレクションから削除してください。
保存する典型的な最小限のものは、dict
追跡する必要がある他のものへのソケットのマッピングです。socket
それ自体、weakref
それへの、またはそれfileno
をキーとして使用できます。多くの場合、必要なデータには、読み取りバッファーと書き込みバッファー、ピア アドレス ( で受信したaccept
もの)、名前、ユーザー ID、または認証 Cookie などが含まれます。
また、各クライアント ソケットに少なくとも読み取りバッファが接続されていないポーリング サーバーで、どのように役立つことを行っているのかわかりません。部分的なメッセージを受け取ったらどうしますか? (さらに言えば、これらのクライアントにメッセージを送信する予定で、書き込みバッファーがない場合、どうすればよいでしょうか?)
しかし、あなたの特定の質問に答えるには:
基礎となる APIでこれを行う方法がないため、Pythonepoll
オブジェクトから fd のリストを取得する方法はありません。
おそらく、0 から最大オープン fd までのすべてをステップ実行し、それを実行しepoll_ctl
てエラーに基づいて区別しようとするものを作成できます。これはおそらく非常に悪い考えですが、不可能ではないかもしれません。おそらくctypes
ネイティブ関数に落とし込む必要があり、何が正しい効果をもたらすかを見つけるために、さまざまな可能性をいじる必要があるかもしれません。たとえば、おそらく、登録されていない fd、存在しない fd をepoll_ctl(my_epoll.fileno(), EPOLL_CTL_MOD, fd, NULL)
取得しますが、 ( NULL のため) 有効な fd を取得します。または、セグメンテーション違反になる可能性があります。区別できるパラメーターの組み合わせがあることは保証できませんが、試行錯誤を重ねることで、1 つが見つかる可能性があります。ENOENT
EBADF
EINVAL
event
(ちなみに、 anepoll
が接続されたクライアントのリストでなければならないということは何もありません。たとえば、接続されたクライアントとリスナー ソケットと "quit" パイプである可能性があります。)