ioctlsocket()の使用方法について

解決


Wada  2007-03-13 16:37:52  No: 64641  IP: 192.*.*.*

はじめまして。
ソケットを使用してTCP/IPの通信ソフトを作成しています。
その中で、受信処理にタイムアウトを設けるためにrecv()関数を
コールする前にioctlsocket()を使用して、ブロッキングモードから
非ブロッキングモードに変更しています。
recv()関数実行後、再びブロッキングモードに戻しています。
このように通信途中で、モードを切り替えても宜しいのでしょうか?
また、他に何か良い方法があれば教えて下さい。
ちなみに、今のところ正常に動作しているように見えます。

開発環境は、Windows2000 SP4 VC6 MFCです。
よろしくお願いします。

編集 削除
yoh2  2007-03-13 22:56:36  No: 64642  IP: 192.*.*.*

タイムアウトを指定したselect()かWSAAsyncSelect()を使ってみるのはいかがでしょう?

編集 削除
とおりすがり  2007-03-14 04:34:13  No: 64643  IP: 192.*.*.*

>また、他に何か良い方法があれば教えて下さい。
パフォーマンス的に最高を求めるのであれば、各種通信を別スレッドとして、マルチスレッドで開発するのがベストになるはずです。ただしシングルスレッドに比べて開発の難度はかなり上がります。

パフォーマンスを求めないならやはりselect()が一番簡単で、信頼性や安定性も高いと思います。

編集 削除
Wada  2007-03-14 14:42:21  No: 64644  IP: 192.*.*.*

yoh2さん、とおりすがりさん
ご回答ありがとうございます。
select()を使用してみることにします。

やはり、ブロッキング、非ブロッキングを
頻繁に切り替えるのは、よくないのでしょうか?

編集 削除
yoh2  2007-03-14 22:33:40  No: 64645  IP: 192.*.*.*

> やはり、ブロッキング、非ブロッキングを
> 頻繁に切り替えるのは、よくないのでしょうか?

これ自体は特に悪いというわけではありませんが、あまり見かけませんね。
あえて挙げるなら、あまり見かけないだけに未知のバグを踏む可能性が高いかも、というあたりですかね。

タイムアウトありの受信処理に非ブロッキング方式を使うデメリットならあります。

まず、受信するまで、ウェイトをかけずに延々とループした場合、無駄にCPUを食ってしまいます。
ならば受信が成功するまで、適切な時間だけスリープしながらループ、といった方法を取ればよい、
ということになりますが、この「適切な時間」というのはなかなか決めにくいものです。
短か過ぎるとCPUを食いますし、長過ぎればレスポンスが悪くなりますし。

その点、select()なら、受信するまではCPU使用率が上がりませんし、パケットが到着次第
それが分かりますから、非ブロッキングでループする方式より優れていると思います。

# ここまで書いていて疑問。みかけ上のCPU使用率は上がりますが、実は非ブロッキングで
# ループ+Sleep(0)で十分かも?

編集 削除
Wada  2007-03-15 13:52:17  No: 64646  IP: 192.*.*.*

> これ自体は特に悪いというわけではありませんが、あまり見かけませんね。
> あえて挙げるなら、あまり見かけないだけに未知のバグを踏む可能性が高いか> > も、というあたりですかね。

ご親切にありがとうございます。
私も見かけたことがなかったので、心配していました。
教えて頂いた通り、select()を使用するように変更しました。
ありがとうございました。

編集 削除