WSAAsyncSelectでsendがブロックする事はありますか?

解決


MenPin  2010-05-31 21:17:11  No: 71683  IP: [192.*.*.*]

もしブロックする事があるとしたら、FD_WRITEにsend処理を書くのでしょうけど、
例えばサーバープログラムのFD_READでデータを受信した直後に、
そのデータを送り返すとしたら、send処理は何処に書いたらいいのでしょうか?
よろしくお願いします。m(_ _)m

編集 削除
瀬戸っぷ  2010-06-01 01:13:41  No: 71684  IP: [192.*.*.*]

ノンブロッキングならば…
send()でブロックすることはない…かと思われます。
# ブロックしないとならない状況であれば、SOCKET_ERROR が返され、
# WSAGetLastError()でWSAEWOULDBLOCKが返されるでしょう。

あとは…Socketの送信バッファより大きいデータをsend()しようとした場合にブロックされるかも知れません。
# send()したのに相手がrecv()で受け取ってくれない状況…だと、
# どこかでデータが詰まるコトになろうかと。
# 相手のSocketの(recv()で渡される前の)受信バッファとこちらの送信バッファの合計を上回った場合…でしょうかね。
# 実験したことはありませんが。

私のプログラムでは圧倒的に受信データの方が多いので…。
send()に失敗する。ということはあまり深く対処していません。
# 念のためWSAEWOULDBLOCKは対策していますが…送信できないと呼び出し元に戻らない…という風になってます。
# 一度だけ報告のあったCPU使用率100%はここなのかなぁ…

>例えばサーバープログラムのFD_READでデータを受信した直後に、
>そのデータを送り返すとしたら、send処理は何処に書いたらいいのでしょうか?

受信データのサイズによるかと。
socketの送信バッファをサイズを越えないことが保証できるなら、recv()の直後でもイイでしょうし、
recv()したデータをある程度バッファして細々とsend()していくのもよいでしょう。
# バッファリングした場合、「リアルタイム」というわけには行かないかも知れませんが。
# 数十〜数百msとかの遅延が出るかも知れない…と。
# まぁ、TCPでそんなに時間にこだわってもしょうもないとは思いますが。

編集 削除
MenPin  2010-06-01 01:30:49  No: 71685  IP: [192.*.*.*]

とても詳しい回答ありがとうございます。
> あとは…Socketの送信バッファより大きいデータをsend()しようとした場合にブロックされるかも知れません。
Socketの送信バッファサイズって何処で調べられますか?
(受信側のrecvのバッファサイズの事でしょうか?
受信側がWSAAsyncSelectで待ってたら、送信側はどれだけデータを送っても、ブロックされることは無いということでしょうか?(受信側のOSのバッファにいくらでも溜まる様なイメージです。それをFD_READで反応して読み込んでいく。合ってますか?

編集 削除
瀬戸っぷ  2010-06-01 23:49:15  No: 71686  IP: [192.*.*.*]

>Socketの送信バッファサイズって何処で調べられますか?

getsockopt()などですかね。
# SO_SNDBUFとSO_RCVBUFあたり。

>受信側がWSAAsyncSelectで待ってたら、送信側はどれだけデータを送っても、ブロックされることは無いということでしょうか?
>(受信側のOSのバッファにいくらでも溜まる様なイメージです。それをFD_READで反応して読み込んでいく。合ってますか?

いくらでも…というワケではないかと。
FD_READで受信バッファから取り出していれば、それなりに行けるとは思いますが。
ノンブロッキングでのsend()の場合、ブロックされる(送信完了(送信バッファに書き込み完了)まで戻ってこない)のではなく、WSAEWOULDBLOCKが返却される…かと。
ブロッキングモードの場合だと、完了するまで処理が戻ってこない…と思われますが。
# 送信バッファよりデータの量が多ければ、順次送信されて空いたバッファに書き込み続けて指定サイズ分書き込むまで戻ってこない…かと。


なお、実際に試したわけではありませんので実装前にテストはして下さい。
# ちょっと無責任…ですが、試している時間がありませんので…。

編集 削除
MenPin  2010-06-02 00:16:33  No: 71687  IP: [192.*.*.*]

回答ありがとうございます。
今作ってるプログラムの送信バッファサイズはそんなに大きくないし、
SO_SNDBUFはデフォルトで8KByteみたいなので、今の所問題なさそうです。
ありがとうございました。

編集 削除