2

私がこのようにしようとすると:

my $sock = IO::Socket::INET->new( … )                    or die "no socket for you";
defined $sock->setsockopt(SOL_SOCKET, SO_RCVTIMEO, 30)   or die "setsockopt: $!";

その後、私のスクリプトは「setsockopt: Invalid argument at [line 2]」で死にます。IO::Socketとpodsはperlfunc言いませんが、perlfunc はTCP_NODELAY上記のように見える例を示しています。

簡単なメモ:私はできる限り自分の質問に答えましたが、確かにより良い答えを歓迎します。最も明白な「より良い」は、少なくともPOSIXマシンでは移植可能であることです)

4

2 に答える 2

5

スクリプトを実行している Perl インタープリターでを使用straceすると、問題は Perl がstruct timeval(によって必要とされるSO_RCVTIMEO) をパックしていないことであることが明らかになります。さらに、それを行うためのヘルパー関数はないようです。代わりに、自分で行う必要があります。

struct timevalマシン固有であるため、これは問題であることが判明しました。Single Unix Specification では次のように定義されています。

ヘッダーは、少なくとも次のメンバーを含む timeval 構造体を定義する必要があります。

time_t         tv_sec        Seconds.
suseconds_t    tv_usec       Microseconds.

また、time_t は整数型または実数浮動小数点型であり、「suseconds_t は、少なくとも範囲 [-1, 1000000] の値を格納できる符号付き整数型でなければならない」 ( sys/types.hを参照) とも述べています。

C 構造体にアクセスしないと、これを移植可能に行うことはできません。しかし、glibc を仮定すると、より制限的な定義があり、両方を として指定しlong、メンバーは 2 つしかないことになります。ただし、これはドキュメントのバグです。だから気にしないでください。

したがって、私ができる最善のことは、GNU/Linux IA-32 と GNU/Linux AMD64 の両方で機能すると私が信じていることです。

$sock->setsockopt(SOL_SOCKET, SO_RCVTIMEO, pack('l!l!', 30, 0))
    or die "setsockopt: $!";

このpack形式l!は、現在のマシンのネイティブを使用することを意味しますlong— これは glibc のドキュメントに書かれていることであり、少なくとも一部の glibc アーキテクチャでは実装されているようです (バグによると SPARC では実装されていません)。

于 2011-11-27T08:04:38.007 に答える
0

$myiosockinet->timeout( 30 );または$myiosockinet->timeout( 30 * 1000000 );動作 しますか?

そうでない場合は、そのモジュール (IO::Socket::INETまたは) を更新Socketする必要があります:) 29%3Fは物足りない

于 2011-11-27T09:29:40.260 に答える