【问题标题】:Perl TCP Socket programming vs C recv() function. Do I need to keep track of bytes received?Perl TCP Socket 编程 vs C recv() 函数。我需要跟踪收到的字节吗?
【发布时间】:2014-04-22 04:37:17
【问题描述】:

我熟悉 C 中的 TCP/IP 编程,但对 Perl 有点陌生。在 C 语言中,您需要围绕 recv() 语句编写一个循环,因为不能保证在一个 recv() 语句中从远程服务器获取所有数据。

while(Size != 0)
 {
  Status = recv(Socket, Buffer, Size, 0);
   Buffer = Buffer + Status;
   Size = Size - Status;
  }

我在 Perl 中看到的几乎所有示例都显示了仅打印您从套接字获得的内容,而不跟踪您收到的字节。

my $new_sock=$sock->accept();
while(<$new_sock>)
 {
  print "$_\n";
 }
 close($sock);

那么,Perl 是否以某种方式确保您获得所有数据而无需计算字节数?

如果答案是否定的,有人可以指出一个像上面的 C 示例一样跟踪的 Perl TCP 代码示例吗?

【问题讨论】:

    标签: c perl sockets tcp


    【解决方案1】:

    &lt; &gt;(readline 函数)级别较高,非常方便。

    IO::Socket 支持recv 方法。

    由于IO::Socket 继承自IO::Handle,您可能还对紧密模拟您正在寻找的低级C 接口的readsysread 方法感兴趣...

    【讨论】:

      【解决方案2】:

      您在 C 中的示例是错误的。 recv 返回 -1 如果由于错误而无法读取,并且在 eof 上返回 0(例如关闭连接),因此您需要退出循环一次 status&lt;=0。 Perl 中的recv 也有类似的行为:它在出错时返回 undef,缓冲区将在 eof 上为 ''。您可以通过检查缓冲区的大小 (length($buf)) 获得读取的字节数。

      但是,在您的示例中,您不使用recv,而是使用&lt;&gt;,类似于getline,例如缓冲 I/O。和 C 中的缓冲 I/O 一样,它会尝试读取,直到满足要求(例如全行读取)或发生 eof。

      因此,对于类似于 freadfwritegetline 的缓冲 I/O 使用 readwrite&lt;&gt;,对于非缓冲 I/O 使用 recvsysread 和 @ 987654339@,其行为与 C 中的 recvreadwrite 相同,例如尽可能多地读/写,但不要不必要地阻塞。

      【讨论】:

      • 嗨,是的,我删除了处理 -1 和 0 返回的几行代码。我只是想展示我是如何在 C 中处理从 recv() 返回的长度的。谢谢。
      【解决方案3】:

      在 C 示例中,您读取了固定数量的字节。在 Perl 示例中,您一直读取到流关闭为止。这两个 sn-ps 是不同的,因为它们执行不同的任务。

      他们甚至不使用相同的工具。 C 示例使用recv(2),而 Perl 示例使用read(2)

      请注意,在未通过其他方式验证您是否已收到完整的流之前,您不应该在流关闭之前阅读。如果连接断开数据包以错误的顺序到达,您最终可能会在不知情的情况下错过流的末尾。 (上世纪 90 年代,我经常使用 FTP 客户端。)Perl 示例不能保证获取所有数据(尽管通常会)。

      【讨论】:

        猜你喜欢
        • 2018-12-18
        • 2017-02-27
        • 2015-02-16
        • 1970-01-01
        • 2015-03-09
        • 2021-12-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多