Perl 程序读取 UDP 数据包并清理数据并传输到另一个端口。
如果没有use POSIX;在程序中,它就不能变成<$sock>数据包。
`$sock` comes from:
Run Code Online (Sandbox Code Playgroud)
`$sock` comes from:
Run Code Online (Sandbox Code Playgroud)
数据正确输入use POSIX:
!AIVDM,1,1,,B,37Oms:?Oh0bHEEMb=j5A5AtL00N0,0*76" (AIS data)
without that, <$data> appears as "GLOB(0x1563bcda6e8)
Run Code Online (Sandbox Code Playgroud)
PERldocs“强烈反对”使用“use POSIX;” https://perldoc.perl.org/POSIX
socket($sock, PF_INET, SOCK_DGRAM, getprotobyname('udp'))
bind($sock, $sockets[0])
Run Code Online (Sandbox Code Playgroud)
应该从套接字给我数据,不带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...
Run Code Online (Sandbox Code Playgroud)
然后您可以通过添加来修复
use POSIX qw(PF_INET SOCK_DGRAM);
Run Code Online (Sandbox Code Playgroud)
或者通过添加
use POSIX ();
Run Code Online (Sandbox Code Playgroud)
并参考POSIX::PF_INET和POSIX::SOCK_DGRAM,如文档所示。只从 POSIX 导入所有内容,这是一个糟糕的主意。
问题是,如果您不导入并且不使用 strict,您将传递字符串 "PF_INET"和"SOCK_DGRAM"to socket,这会被默默地解释为完全错误的东西(可能是与 number 对应的任何套接字类型和协议0)。套接字创建可能完全失败,但您没有检查$!错误,因此您永远不会发现它。
使用 90 年代的任何东西都是Socket相当POSIX的。它迫使您执行大量容易出错的手动工作,并且需要对 IPv4 和 IPv6 进行不同的调用。在 perl 5.20+ 上你可以改为
use IO::Socket::IP;
my $sock = IO::Socket::IP->new(Proto => 'udp', LocalPort => $port)
or die "listening on udp/$port: $IO::Socket::errstr";
Run Code Online (Sandbox Code Playgroud)
它用一个更易读的调用替换了对sockaddr_in、getprotobyname、socket、 和 的调用。bind您从中获得的套接字的工作方式与您从 中获得的套接字的工作方式完全相同socket。
如果由于某种原因你的 perl 已经超过 9 年了,你可以IO::Socket::INET使用IO::Socket::IP. 除了 IPv6 支持之外,它的工作原理类似,并且自 2000 年以来一直处于核心地位。
如果您正在阅读的教程或其他内容告诉您如何以 25 年前过时的方式做事,您可能想扔掉它。
| 归档时间: |
|
| 查看次数: |
63 次 |
| 最近记录: |