3

我有一个 perl 服务器端套接字,它在客户端套接字上调用 send() 逐个返回字段。

如果代码如下所示,我在客户端读取所有字段时没有问题:

while ($response = <$sock>) {
print "$response";
last if $response eq "END_OF_REQUEST";
}

但是,如果客户端代码如下所示,它将进入循环并且无法正常工作:

while(1) {      
$sock->recv($response, 1);
print "$response\n";    
last if $response eq "END_OF_REQUEST" ;
}

我同意我可以使用所有字段并在服务器端仅调用一次发送。但我有兴趣知道第二种方法有什么问题。在第二种方法中更改 recv 的 LENGTH arg 是否有效?

在没有关于套接字的适当理论知识的情况下,我开始直接动手。谢谢你的耐心。

4

1 回答 1

4

长度参数recv()是您想要接收的消息的最大recv()长度,并且永远不会将超过那么多字符写入缓冲区。(消息的其余部分会发生什么取决于套接字的类型;对于流式套接字,它将可用于下一次recv()调用,而对于数据报套接字,它只是被丢弃。)

因此,您$sock->recv($response, 1);最多只能将一个字符写入$response. 显然,一个单字符的字符串永远不会等于"END_OF_REQUEST"

简单的解决方案是将足够大的最大长度传递给recv(),这样您的消息就不会被截断。


这是一个简单的演示:

use strict;
use warnings;
use IO::Socket;

my ($rd, $wr) = IO::Socket->socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC)
    or die "socketpair: $!";
defined $wr->send("Hello, world!") or die "send: $!";
my $buf;
do {
    defined $rd->recv($buf, 9) or die "recv: $!";
    print qq(received: "$buf"\n);
} while ($buf !~ /!/);

这将输出:

received: "Hello, wo"
received: "rld!"
于 2013-01-21T18:34:27.740 回答