当数据长度未知时,从 Perl 中的套接字接收数据的最佳方法是什么?
现在,我在循环中一次读取一个字符,直到到达 \0
字符。有更好的方法吗?
Right now, I read one character at a time in a loop, until I reach the \0
character. Is there a better way to do this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
将行结尾设置为
\x{00}
(\0),确保对其进行本地化,并在句柄上设置getline
,如下所示:Set your line ending to
\x{00}
(\0), be sure to localise it, andgetline
on the handle, like so:您可以将
FIONREAD
与ioctl
。下面的程序连接到本地主机上的 SSH 服务器并等待其问候语:示例运行:
但您可能更喜欢使用
IO::Socket::INET
和IO::Select
模块,如下面与 Google 对话的代码:输出:
You could use
FIONREAD
withioctl
. The program below connects to the SSH server on localhost and waits on its greeting:Sample run:
But you'll probably prefer using the
IO::Socket::INET
andIO::Select
modules as in the code below that talks to Google:Output:
对于任何语言来说,解决这个问题都是不可能的。如果您不知道数据长度有多长,那么您就不可能知道何时从套接字接收完所有数据。
您唯一的希望是使用某种指标来确定自数据开始进入以来是否“足够长”,以做出数据流已停止的决定。但它不会是完美的。
A sound solution to this is impossible, in any language. If you don't know how long the data length is, then you can't possibly know when you've finished receiving all of it from the socket.
Your only hope is to use some kind of a metric to determine if it's been "long enough" since data started coming in, to make the decision that data flow has stopped. But it won't be perfect.
答案取决于协议。由于您的协议使用“\0”作为分隔符,因此您正在做正确的事情。我很确定 Perl 会为您处理缓冲,因此一次读取一个字符并不是低效的。
许多面向网络的协议在字符串之前都有一个长度。要读取这样的协议,您需要读取长度(通常是一个或两个字节,具体取决于协议规范),然后将那么多字节读入字符串中。
The answer depends on the protocol. Since your protocol uses '\0' as a separator, you're doing the right thing. I'm pretty sure Perl handles buffering for you, so reading one character at a time is not inefficient.
Many network oriented protocols precede strings with a length. To read a protocol like this, you read the length (usually one or two bytes, depending on the protocol spec), then read that many bytes into a string.
您可以使用 sysread 读取任何可用数据:
Perl 的 read 函数等待您请求的完整字节数或 EOF。
这与 libc stdio
fread(3)
类似。Perl 的
sysread
函数一旦收到任何数据就会返回。这类似于 UNIX
read(2)
。请注意,
sysread
会绕过缓冲 IO,因此请勿将其与缓冲read
混合。检查
perldoc -f read
和perldoc -f sysread
了解更多信息。对于这个具体问题,最好遵循最上面的答案,并使用
getline
和行尾\0
,但我们可以使用sysread< /code> 如果没有终止字符。
这是一个小例子。它请求一个网页,并打印收到的第一块数据。
You can use
sysread
to read whatever data is available:Perl's
read
function waits for the full number of bytes that you requested, or EOF.This is similar to libc stdio
fread(3)
.Perl's
sysread
function returns as soon as it receives any data.This is similar to UNIX
read(2)
.Note that
sysread
bypasses buffered IO, so don't mix it with the bufferedread
.Check
perldoc -f read
andperldoc -f sysread
for more info.For this specific question, it would be better to follow the top answer, and use
getline
with a line-ending of\0
, but we can usesysread
if there is no terminating character.Here's a little example. It requests a web page, and prints the first chunk of data received.