我正在尝试通过一个小的Perl学习项目,该项目需要从套接字中读取4个无符号整数.我无法获得超过1个整数读取,并在挖掘后找到了解决方案.但我需要了解我做得不对(并且经历过几本Perl书籍,perldocs等等都无济于事.)
示例1:这是成功的解决方案代码(原始),假设下面的套接字连接成功:
{
local $/ = \16; # make <> read in 16 bytes with one swoop.
my @integers = unpack "IIII", <$sock>;
print "numbers: @val\n";
}
Run Code Online (Sandbox Code Playgroud)
例2:我在下面尝试过这个.如果我在解压缩之前打印输入,我只得到一个整数:
my $input;
$sock->recv($input,16,0);
my @integers = unpack("IIII", $input);
Run Code Online (Sandbox Code Playgroud)
具体问题:
任何帮助,指针等都表示赞赏.顺便说一下,"学习项目"是一个非常酷的东西.
您的套接字是TCP还是UDP?
recv是比<>/ 低的例程readline。它或多或少直接映射到recv(2)系统调用。如果套接字数据以4个4字节的数据包的形式到达,recv即使看到了第一个数据包,它也会立即返回,即使它已被提供了更大的缓冲区。如果所有4个数据包在第一次调用之前到达recv(),那么是否要获取所有数据还是仅获取一个数据,可能取决于它是TCP还是UDP。
如果您使用的是TCP,则数据包可能会在传输中被分段。对于16字节的有效负载,这种情况不太可能发生,但是最佳实践是不要假定即使您知道服务器一次发送所有数据,也无法一次显示全部16字节的数据。通常期望网络应用程序缓冲传入的数据,或者,您可以通过使用指定16字节记录来让perl为您完成$/ = \16。
我发现比<>这种I / O用法更自然的另一种可能性是使用reador sysread函数(或OO等效项,它们在IO::Socket超类中定义IO::Handle)。它们带有一个长度参数,但是像以前一样,您不应假定整个缓冲区都将被立即填充。
至于1)
好吧,<>接受任何文件句柄,包括套接字。按照惯例,您可以将其留空,在这种情况下,会假定某种合理的默认行为。请参阅perldoc perlop(在里面搜索<>)。
特殊变量$/是记录分隔符,默认为“\n”。您可以取消定义它并立即读取整个文件(这称为 slurping)。perldoc perlvar更多内容请参见(\number案例也在那里)。
| 归档时间: |
|
| 查看次数: |
4634 次 |
| 最近记录: |