der*_*ert 2 sockets perl setsockopt io-socket
如果我这样尝试:
my $sock = IO::Socket::INET->new( … ) or die "no socket for you";
defined $sock->setsockopt(SOL_SOCKET, SO_RCVTIMEO, 30) or die "setsockopt: $!";
Run Code Online (Sandbox Code Playgroud)
然后我的脚本因“setsockopt:[第 2 行] 处的无效参数”而死亡。在IO::Socket和perlfunc豆荚不说,虽然perlfunc给出了一个例子TCP_NODELAY,这使它看起来像上面应该工作。
(快速说明:我已经尽我所能回答了我自己的问题,但当然欢迎更好的答案。最明显的“更好”是它具有便携性,至少在 POSIX 机器上)
通过strace在运行脚本的 Perl 解释器上使用,很明显问题在于 Perl 没有为您打包struct timeval(需要SO_RCVTIMEO)。此外,似乎没有辅助功能可以为您完成此操作。相反,你必须自己做。
结果证明这是有问题的,因为它struct timeval是特定于机器的。单一 Unix 规范定义了它:
标题应定义时间值结构,该结构至少应包括以下成员:
Run Code Online (Sandbox Code Playgroud)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: $!";
Run Code Online (Sandbox Code Playgroud)
该pack格式l!意味着使用当前机器的本机long——这就是 glibc 文档所说的,并且显然至少为某些 glibc 体系结构(但不是 SPARC,根据错误实现)。
| 归档时间: |
|
| 查看次数: |
3915 次 |
| 最近记录: |