2013-05-02 17 views
5

私はrecvmmsg()を使用したcを使用して単純なアプリケーションを構築し、渡された5番目のパラメータはタイムアウトがtype struct timespecです。タイムアウトを5秒に設定しましたが、動作しません。無限にブロックされます。以下のようrecvmmsg()でタイムアウトを設定するには?

コードは次のとおりです。

struct timespec timeout; 

timeout.tv_sec = 5; 
timeout.tv_nsec = 0; 

result = recvmmsg(fd, datagrams, BATCH_SIZE, 0, &timeout); 
+1

関連性のある可能性のあるバグの提案があります。http://lists.openwall.net/netdev/2012/12/23/30 – Vicky

+0

@Vicky:これは正しいことです - 私のリンクに似ています回答。しかし、誰もが動作を変更しようとしていることは明らかではありません。マニュアルバグと考えられ、マニュアルページが更新され、ほとんど役に立たないタイムアウトパラメータはほとんどのアプリケーションでは使用されません。 –

+0

上記のリンクには、selectを使用した別の解決策があります:http://stackoverflow.com/questions/12713438/how-to-add-delay-to-sento-and-recvfrom-in-udp-client-server-in- c – MOHAMED

答えて

4

setsockoptSO_RCVTIMEOオプションを使用すると、ソケット。これは、それに対して実行されるすべての読み取り操作に影響します。

5

はこちらをご覧ください:http://permalink.gmane.org/gmane.linux.man/3440

基本的にタイムアウトパラメータがより多くのメッセージを待機する時間の最大量を指定しますが、根本的な操作がまだブロックして受け取ります。したがって、5秒のタイムアウトを設定して1秒ごとに1つのメッセージを受信すると、バッファ内にさらに多くのスペースがあっても(約)5個のメッセージを受信した後で停止します。データがまったくない場合は、5秒後にリターンします。そのためには、select()やepoll()のようなタイムアウトやビジー状態の待ちなどの通常のメカニズムを使用する必要があります。

+0

これは有用で意図されたユースケースを想像することはできません。 – PlasmaHH

+0

この回答のリンクから、私は非常に説明的な見積もりを見つけました。recvmmsg()は明示的なタイムアウトパラメータを持っていますが、それは のようには見えず、ドキュメンテーションはSO_RCVTIMEOとの対話方法について言及していません。 " 'recvmmsg()'タイムアウトパラメータを無期限にブロックしたくない場合は、なぜソケットの 'SO_RCVTIMEO'パラメータを設定しなければならないのかが説明されているので参考になりました。 (私のrecvmmsgテストコード( 'man recvmmsg'から)は、1秒のタイムアウトで無期限にブロックされます。ソケットのSO_RCVTIMEOを設定すると、無期限にブロックされません。 –

0

recvmmsgの実装にバグがあります:

お知らせ、pselectは、データが利用可能であるかどうかをチェックすることができますが。しかし、それはrecvmmsgが永遠に待たないことを保証するものではありません。したがって、このメソッドを使用しないでください。

recvmmsgのtimeoutの文字列にSO_RCVTIMEOを追加することをお勧めします。 SO_RCVTIMEO以降、またはtimeout以降にデータが受信されなかった場合、recvmmsgは終了します。最悪の場合、timeout + SO_RCVTIMEOの後にrecvmmsgが終了します(データが最後に受信された場合は、timeoutのデータが到着しません)。

関連する問題