プロが教える店舗&オフィスのセキュリティ対策術

C言語でネットワークプログラミング(ストリーミングのプログラムを作成しました)
UDPを使用したプログラミングなのですが、サーバ側でデータを送るのが途中でいったん停止することがあるんです。数秒停止してまた送る。
もしクライアント側で何か処理が止まったときに、
ソケットのsendto(。。。。。)がブロックするのであればそのエラーもなっとくいくのですが。
sendtoってブロックするのでしょうか??
recvfrom()はソケットディスクリプタに応答があるまでブロックするのはわかるのですが・・・。sendtoはお構いなしに送信するんだったと思うのですが。
環境はサーバ、クライアントマシンともにlinux7.2です。

A 回答 (1件)

sendto()のマニュアルにもありますが、socketがノンブロッキングモードでない限り、そのsocket用の送信データスペース(バッファ)が足りないと、ブロックします。

CPUが速い場合やネットワークが混んでいる場合に起きる可能性があります。

UDPはいくらパケットの到着を保証しないといっても、送信側でCPUが速すぎたから消えるんではあんまりですよね?UDPでパケットが消えるのは、中継のルータでバッファがあふれたときくらいです。

もし、ノンブロッキングモードにしたいなら、setsockopt()とSO_SNDTIMEOオプションが絡むと思いますが、試したことはないのでわかりません。必要なら調べてみてください。でもこれをすると、バッファがあふれて送れない状況が頻出するのであまり好ましくないとは思います。
バッファの大きさもsetsockopt()で変更できるはずです。

送信側が本当にいつパケットを出したかを知るのは大変かもしれません。tcpdumpやetherealでパケットモニタリングできますが(スイッチングハブ越しではもちろん無理)、それでもモニタリングしているPCで受信した時刻しかわからないと思います。送信側PCで同時にモニタリングしてもいいでしょうが、別のプロセスが走る状況が好ましいかどうかによります。

バッファを最小限にしてsendto()が-1を返してerrno==EWOULDBLOCKだったら再送して、成功したときにその時刻を調べるというのアイデアもありそうです。
結局のところ、本当に知りたい時刻は何かということですが。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!