[英]recv() with length zero is valid?
使用C中的recv()函数从'stream'套接字读取,len参数可以为零吗?
recv()函数为'远程连接关闭'返回零,并且在正常操作时实际读取的字节数,因此如果它应该读取零字节则听起来有问题。
PS
是的我知道单独处理它,并没有达到这种情况,仍然我想知道该功能是否可以处理它,我找不到任何关于它的文档。
我相信答案是“这取决于”。 如果标准没有规定 (事实上我认为不是),任何实施都可以随心所欲。
EINVAL
而失败 0
并继续 gcc
用来做那:))) 实际上在我的实现上,它返回0并继续。 要检查它是否失败或只是返回0,您可以在通话后检查errno
,因此它不像您想象的那样有问题。
我系统上的recv
文档(Linux)说
如果套接字上没有可用消息,则接收呼叫等待消息到达
和
如果消息太长而无法容纳在提供的缓冲区中,则可能会丢弃多余的字节,具体取决于接收消息的套接字类型。
根据文档,我希望我的recv
等待消息,然后有效地丢弃它(UDP)或将其保留在流(TCP)中。
这可用于测试非阻塞TCP套接字是否有数据等待。
更新 :测试显示文档的这种解释是准确的。
服务器:
$ perl -MIO::Socket::INET -E'
my $s = IO::Socket::INET->new(Listen => 1) or die $!;
say $s->sockport;
my $c = $s->accept or die $!;
say "[".localtime."] connected";
$c->recv(my $buf, 0) // die $!;
say "[".localtime."] received";
say <$c>;
'
39493
[Fri May 13 13:49:53 2011] connected
[Fri May 13 13:49:55 2011] received
foo
客户:
$ perl -MIO::Socket::INET -E'
my $s = IO::Socket::INET->new(
PeerAddr => "127.0.0.1",
PeerPort => $ARGV[0],
) or die $!;
sleep 2;
say $s "foo";
' 39493
(这些Perl函数只是系统调用的瘦接口。可以在C中重写它们。)
我很确定它是未定义的...看着Linux它一直传递到“驱动程序”(即.tcp等),所以它可能意味着什么,但我再也不认为这个含义是定义好的。 当然SuS并没有明确说明这一点。
我认为你几乎肯定更好,只是不这样做,并使用MSG_PEEK与1字节或poll()取决于你想做什么。
POSIX关于recv()
的页面并不是很清楚。 在非规范部分(“应用程序使用”)中,如果没有给出标志,它表示套接字上的recv()
等效于read()
。 POSIX关于read()
的页面表示读取0字节可能会检查错误; 如果没有错误或者实现没有检查,则没有任何反应,返回0。
我不认为长度参数可以为零,因为即使空字符串(消息)需要以'\\ 0'终止。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.