perl - socket->recv() 与 <>?

标签 perl sockets recv

我正在尝试完成一个需要从套接字读取 4 个无符号整数的小型 Perl 学习项目。我无法读取超过 1 个整数,经过深入研究后,我找到了解决方案。但是我需要了解我没有做对的事情(并且已经阅读了几本 Perl 书籍、perldocs 等,但无济于事。)

示例 1:
这是成功的解决方案代码( original ),假设套接字连接成功用于以下两个:

{
  local $/ = \16; # make <> read in 16 bytes with one swoop.
  my @integers = unpack "IIII", <$sock>;
  print "numbers: @val\n";
}

示例 2:我在下面尝试过。如果我在解包之前打印输入,我只会得到一个整数:
my $input;
$sock->recv($input,16,0);
my @integers = unpack("IIII", $input);

具体问题:
  • 在示例 1 中,“$/”到底是什么?它如何“改变”<>,我认为它读的是标准输入?
  • 在示例 2 中,为什么我的 recv() 从套接字中取出的整数不超过一个?我的理解(每个 perldoc)是“SIZE”参数默认为“bytes”,整数为 4 个字节?

  • 任何帮助,指针等表示赞赏。顺便说一句,“学习项目”是 overthewire.org - 非常酷的东西。

    最佳答案

    你的socket是TCP还是UDP?
    recv是比 <> 低级的例程/readline .它或多或少直接映射到 recv(2)系统调用。如果套接字数据作为 4 个 4 字节的数据包到达,recv即使已经提供了更大的缓冲区,它也会在看到第一个数据包后立即返回。如果所有 4 个数据包在第一次调用 recv() 之前到达,那么您是否获得所有数据或仅获得一份数据可能取决于它是 TCP 还是 UDP。

    如果您使用的是 TCP,则数据包可能会在传输过程中被分段。 16 字节的有效负载不太可能发生这种情况,但最佳实践是不要假设 16 字节的数据会一次全部显示出来,即使您知道服务器一次发送了所有数据。网络应用程序通常需要缓冲传入的数据,或者,您可以通过使用 $/ = \16 指定 16 字节记录来让 perl 为您做这件事。 .

    另一种可能性,我发现它比 <> 更自然对于这种 I/O 用法,是使用 readsysread函数(或 OO 等价物,在 IO::Socket 父类(super class) IO::Handle 中定义)。那些需要一个长度参数,但和以前一样,你不应该假设整个缓冲区会被一次填满。

    关于perl - socket->recv() 与 <>?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5599585/

    相关文章:

    某些客户的 iOS TCP 套接字失去连接

    c - select() 是否保证所有数据都可用于从套接字读取或仅部分数据

    perl - 在使用 -T 开关运行时,DBI::db=HASH(0xa32bd40)->do method call 的参数 3 中显示错误 Insecure dependency

    xml - Perl XML-SAX-Expat 外部实体位置

    java - 客户端断开连接后,Socket isClosed() 返回 false

    php - 无限循环

    python - 更高效地编写 HTTP 脚本

    perl - 使用任何有效的方法(PERL、SED、AWK)将文件行中的信息提取到列中

    c++ - recv() 没有获取客户端使用 send() 发送的所有数据

    C 套接字 - 接收 : connection reset by peer