我熟悉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示例一样保持跟踪吗?
答案 0 :(得分:1)
< >
(readline函数)水平相当高,非常方便。
IO::Socket
支持recv
方法。
由于IO::Socket
继承自IO::Handle
,您可能也会对read
或sysread
方法感兴趣,这些方法会模拟您所关注的低级C接口。重看...
答案 1 :(得分:1)
你在C中的例子是错误的。 recv
如果由于错误和eof上的-1
而无法读取(例如关闭连接),则会返回0
,因此您需要在status<=0
之后退出循环。类似的行为是Perl中的recv
:它在错误时返回undef,缓冲区在{e}上为''
。并通过检查缓冲区的大小(length($buf)
)来获取读取的字节数。
但是,在您的示例中,您不使用recv
,而是<>
,它与getline
类似,例如缓冲I / O.和C中的缓冲I / O一样,它将尝试读取,直到满足要求(例如全线读取)或发生eof。
对于类似于fread
,fwrite
和getline
的缓冲I / O使用read
,write
和<>
,对于无缓存的I / O使用recv
,sysread
和syswrite
,其行为与C recv
,read
和write
相同,例如尽可能读/写但不要不必要地阻塞。
答案 2 :(得分:1)
在C示例中,您读取固定数量的字节。在Perl示例中,您将读取直到关闭流。这两个片段不同,因为它们执行不同的任务。
他们甚至不使用相同的工具。 C示例使用recv(2)
,而Perl示例使用read(2)
。
请注意,在关闭流之前,您应该永远不会阅读,而不会通过其他方式验证您已收到完整的流。如果连接拆除数据包以错误的顺序到达,您最终可能会在不知道它的情况下错过流的末尾。 (曾经在90年代使用FTP客户端发生在我身上。)Perl示例不能保证获得所有数据(尽管通常会这样)。