web-dev-qa-db-ja.com

受け入れソケットを非ブロッキングにすることは可能(そして安全)ですか?

ブロッキングソケットで accept() 呼び出しを中断する方法を探しています。シグナルを使用することはオプションではありません。これはライブラリ内にあることを意図しており、ユーザーシグナルを乱雑にしたくないからです。 select()を使用することも別のオプションですが、さまざまな理由から、私の場合はあまり魅力的ではありません。

可能であれば、ソケットがブロックされている間に、別のスレッドからソケットを非ブロックモードに設定する( fcntl() および_O_NONBLOCK_を使用)ことでうまくいくでしょうaccept()呼び出しで。予想される動作は、accept()呼び出しがEAGAINまたはEWOULDBLOCKerrnoで返されることです。

それは確かにそのように機能しますか?安全ですか?ポータブル?

このメソッドのWindowsへの適用性( WSAIoctl() および FONBIO を使用する必要がある場合)を知っているなら、私はまた興味があります。

12
Norswap

Windowsについてはわかりませんが、必要な動作はPOSIXによって保証されています。

リッスンキューに接続要求がなく、ソケットのファイル記述子にO_NONBLOCKが設定されていない場合、accept()は接続が存在するまでブロックします。 listen()キューに接続要求がなく、ソケットのファイル記述子にO_NONBLOCKが設定されている場合、accept()は失敗し、errnoを[EAGAIN]または[EWOULDBLOCK]に設定します。

出典: http://pubs.opengroup.org/onlinepubs/9699919799/functions/accept.html

また、selectまたはpollを使用して、読み取りセット内のリスニングソケットをポーリングすることにより、着信接続を確認できます。

質問では、IO多重化の最良の方法であるselect(またはpollまたはepoll)を使用したくないと言っています。リスニングのためだけに別のスレッドを使用することをお勧めしますこれは悪い考えですが、ソケット!

0
Amir Fo