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
;它此时挂起。
首先,您应该添加
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 年以来一直是核心。