使用C中的recv()函数从'stream'套接字读取,len参数可以为零吗?
recv()函数为'远程连接关闭'返回零,并且在正常操作时实际读取的字节数,因此如果它应该读取零字节,则听起来有问题。
P.S。
是的我知道单独处理它,并没有达到这种情况,我仍然想知道函数是否可以处理它,我找不到任何关于它的文档。
答案 0 :(得分:4)
我相信答案是“这取决于”。 如果标准未指定(事实上我认为不是),任何实施都可以随心所欲。
EINVAL
0
并继续gcc
曾经这样做:)))实际上在我的实现上,它返回0并继续。要检查它是否失败或只是返回0,您可以在通话结束后检查errno
,这样就不会出现问题。
答案 1 :(得分:3)
我系统上的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中重写它们。)
答案 2 :(得分:1)
我很确定它是未定义的...看着Linux它一直传递到“驱动程序”(即.tcp等)所以它可能意味着什么,但我再也不认为这意味着定义得很好。当然,SuS没有明确说明这一点。
我认为你几乎肯定更好,只是不这样做,并使用MSG_PEEK 1字节或poll()取决于你想做什么。
答案 3 :(得分:0)
POSIX关于recv()
的页面并不是很清楚。在非规范部分(“应用程序使用”)中,如果没有给出标志,则套接字上的recv()
等同于read()
。 POSIX关于read()
的页面表示读取0字节可能会检查错误;如果没有错误或者实现没有检查,则没有任何反应,返回0。
答案 4 :(得分:-3)
我认为长度参数不能为零,因为即使空字符串(消息)需要以'\ 0'终止。