如何在Perl中的套接字上设置`SO_RCVTIMEO`?

zxlwwiss  于 10个月前  发布在  Perl
关注(0)|答案(2)|浏览(90)

如果我这样尝试:

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

字符串
那么我的脚本会因为“setsockopt:[行2]处的参数无效"。IO::Socketperlfunc pod没有说明,尽管perlfunc给出了一个TCP_NODELAY的例子,使其看起来像上面应该工作。
(**快速说明:**我已经尽我所能回答了我自己的问题,但当然欢迎更好的答案。最明显的“更好”是它是可移植的,至少在POSIX机器上是这样)

30byixjq

30byixjq1#

通过在运行脚本的Perl解释器上使用strace,很明显问题在于Perl没有为您打包struct timevalSO_RCVTIMEO需要)。此外,似乎没有帮助函数为您做这件事。相反,你必须自己做。
这是有问题的,因为struct timeval是特定于机器的。单一Unix规范defines it
<sys/time.h>头应定义timeval结构,该结构应至少包括以下成员:

time_t         tv_sec        Seconds.
suseconds_t    tv_usec       Microseconds.

字符串
它还说time_t是一个整数或实浮点类型,并且“suseconds_t应该是一个有符号整数类型,能够存储至少在[-1,1000000]范围内的值”(参见sys/types.h)。
如果不能访问C结构,就不可能以可移植的方式完成这项工作。但是如果我们假设glibc,它有一个更严格的定义,将两者都指定为long,并且它们是仅有的两个成员。但是,this is a documentation bug。所以没关系。
所以,我能做的最好的,我相信在GNU/Linux IA-32和GNU/Linux AMD 64上都可以工作,是这样的:

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


pack``l!意味着使用当前机器的本机long--这是glibc文档所说的,显然至少在一些glibc架构中实现了(但根据bug,不是SPARC)。

liwlm1x9

liwlm1x92#

$myiosockinet->timeout( 30 );$myiosockinet->timeout( 30 * 1000000 );是否有效?
如果没有,则该模块(IO::Socket::INETSocket)需要更新:)因为http://search.cpan.org/~flora/perl-5.14.2/pod/perlfaq8.pod#Where_do_I_get_the_include_files_to_do_ioctl%28%29_or_syscall%28%29%3F不令人满意

相关问题