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:[第 2 行] 的无效参数”而死亡。和pod 没有说,尽管 perlfunc 给出了一个例子IO::Socket,使它看起来像上面应该工作。perlfuncTCP_NODELAY

快速说明:我已经尽我所能回答了我自己的问题,但当然欢迎更好的答案。最明显的“更好”是它是可移植的,至少在 POSIX 机器上)

4

2 回答 2

5

通过strace在运行脚本的 Perl 解释器上使用,很明显问题在于 Perl 没有为您打包struct timeval(required by SO_RCVTIMEO)。此外,似乎没有辅助功能可以为您执行此操作。相反,你必须自己做。

事实证明这是有问题的,因为struct timeval它是特定于机器的。单一 Unix 规范对其进行了定义

标头应定义 timeval 结构,该结构应至少包括以下成员:

time_t         tv_sec        Seconds.
suseconds_t    tv_usec       Microseconds.

它还说 time_t 是整数或实浮点类型,并且“suseconds_t 应该是能够存储至少在 [-1, 1000000] 范围内的值的有符号整数类型”(参见sys/types.h)。

如果不访问 C 结构,就不可能便携地执行此操作。但是如果我们假设 glibc 有一个更严格的定义,将两者都指定为long,并且它们是唯一的两个成员。但是,这是一个文档错误。所以没关系。

所以,我能做的最好的,我相信它适用于 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,根据 bug)。

于 2011-11-27T08:04:38.007 回答
0

有用 吗$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不满意

于 2011-11-27T09:29:40.260 回答