Windows 上 Strawberry 上的 Perl 程序需要“使用 POSIX”才能评估 <$sock> 并从端口读取数据包

问题描述 投票:0回答:1

Perl 程序读取 UDP 数据包并清理数据并传输到另一个端口。
如果程序中没有

use POSIX;
,则无法将
<$sock>
转换为数据包。

`$sock` comes from:
    socket($sock, PF_INET, SOCK_DGRAM, getprotobyname('udp'))
    bind($sock, $sockets[0])

使用

use POSIX
数据正确输入:

!AIVDM,1,1,,B,37Oms:?Oh0bHEEMb=j5A5AtL00N0,0*76" (AIS data)
without that, <$data> appears as "GLOB(0x1563bcda6e8)

PERldocs“强烈反对”使用“use POSIX;” https://perldoc.perl.org/POSIX

    my $data = <$sock>;

应该从套接字给我数据,没有

use POSIX
;它此时挂起。

windows perl posix handle
1个回答
0
投票

首先,您应该添加

use strict
,它会告诉您为什么您的程序在没有POSIX的情况下无法工作:
PF_INET
SOCK_DGRAM
未定义。启用严格性后,您会收到类似的错误

Bareword "PF_INET" not allowed while "strict subs" in use at...
Bareword "SOCK_DGRAM" not allowed while "strict subs" in use at...

然后您可以通过添加来修复

use POSIX qw(PF_INET SOCK_DGRAM);

或添加

use POSIX ();

并参考

POSIX::PF_INET
POSIX::SOCK_DGRAM
,如文档所示。 只从 POSIX 导入所有内容,这是一个糟糕的主意。

然而,使用

Socket
POSIX
中的任何东西都已经是 90 年代的事了;它迫使您进行大量容易出错的手动工作,并且需要对 IPv4 和 IPv6 进行不同的调用。在 Perl 5.20+ 上你可以改为

use IO::Socket::IP;
my $sock = IO::Socket::IP->new(Proto => 'udp', LocalPort => $port);

用一个更易读的调用替换了对

sockaddr_in
getprotobyname
socket
bind
的调用。您从中获得的套接字的工作方式与您从
socket
获得的套接字的工作方式完全相同。

如果由于某种原因你的 Perl 已经使用超过 9 年了,你可以使用

IO::Socket::INET
而不是
IO::Socket::IP
。除了 IPv6 支持之外,它的工作原理类似,并且自 2000 年以来一直是核心。

© www.soinside.com 2019 - 2024. All rights reserved.