Perl TCP Socket编程与C recv()函数。我是否需要跟踪收到的字节数?

时间:2014-04-21 19:53:28

标签: c perl sockets tcp

我熟悉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是否确保您无需计算字节数就可以获得所有数据?

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

3 个答案:

答案 0 :(得分:1)

< >(readline函数)水平相当高,非常方便。

IO::Socket支持recv方法。

由于IO::Socket继承自IO::Handle,您可能也会对readsysread方法感兴趣,这些方法会模拟您所关注的低级C接口。重看...

答案 1 :(得分:1)

你在C中的例子是错误的。 recv如果由于错误和eof上的-1而无法读取(例如关闭连接),则会返回0,因此您需要在status<=0之后退出循环。类似的行为是Perl中的recv:它在错误时返回undef,缓冲区在{e}上为''。并通过检查缓冲区的大小(length($buf))来获取读取的字节数。

但是,在您的示例中,您不使用recv,而是<>,它与getline类似,例如缓冲I / O.和C中的缓冲I / O一样,它将尝试读取,直到满足要求(例如全线读取)或发生eof。

对于类似于freadfwritegetline的缓冲I / O使用readwrite<>,对于无缓存的I / O使用recvsysreadsyswrite,其行为与C recvreadwrite相同,例如尽可能读/写但不要不必要地阻塞。

答案 2 :(得分:1)

在C示例中,您读取固定数量的字节。在Perl示例中,您将读取直到关闭流。这两个片段不同,因为它们执行不同的任务。

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

请注意,在关闭流之前,您应该永远不会阅读,而不会通过其他方式验证您已收到完整的流。如果连接拆除数据包以错误的顺序到达,您最终可能会在不知道它的情况下错过流的末尾。 (曾经在90年代使用FTP客户端发生在我身上。)Perl示例不能保证获得所有数据(尽管通常会这样)。