使用C中的recv()函數從'流'套接字讀取len參數可以爲零嗎?長度爲零的recv()是否有效?
recv()函數對於'遠程連接關閉'返回零和正常操作中實際讀取的字節數,所以如果它應該讀取零字節聽起來有問題。
P.S.
是的,我知道單獨處理它,並沒有得到這種情況,我仍然想知道該功能是否可以處理它,我找不到任何有關它的文檔。
使用C中的recv()函數從'流'套接字讀取len參數可以爲零嗎?長度爲零的recv()是否有效?
recv()函數對於'遠程連接關閉'返回零和正常操作中實際讀取的字節數,所以如果它應該讀取零字節聽起來有問題。
P.S.
是的,我知道單獨處理它,並沒有得到這種情況,我仍然想知道該功能是否可以處理它,我找不到任何有關它的文檔。
我相信答案是「取決於」。 如果它沒有被標準(並且實際上我相信它不是)規定的,任何實現都可以按照它的意願進行。
EINVAL
0
,繼續gcc
: )))其實在我的實現中,它返回0並繼續。要檢查它是否失敗或只是返回0,您可以在電話後檢查errno
,因此它不像您想象的那樣有問題。
我不認爲長度參數可以是零,因爲即使是一個空字符串(消息)需要終止'\ 0'。
來自套接字的「消息」不一定是以nul結尾的字符串。 – 2011-05-13 16:29:14
...並不一定是一個字符串:-D – 2011-05-13 16:31:05
好吧,我的壞。注意到了。儘管C語言允許,但我仍然認爲零字節緩衝區的概念值得商榷。 – 2011-05-13 18:10:38
我很確定它是未定義的......看着Linux它一直傳遞到「驅動程序」(即.tcp等),所以它可能意味着什麼,但我不認爲這是意義被很好地定義。當然,SuS並沒有對此做任何明確的說明。
我認爲你幾乎可以肯定不會這樣做,並且根據你想要做的事情使用帶有1字節或poll()的MSG_PEEK。
爲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.)
POSIX的頁面約recv()
是不是很清楚它。在非標準部分(「應用程序使用」)中,如果沒有給出標誌,則說明在套接字上的recv()
相當於read()
。 POSIX的頁面read()
表示讀取0字節可能會檢查錯誤;如果沒有錯誤或執行不檢查,則不會發生任何事情並返回0。
你試過了嗎? – BlackBear 2011-05-13 16:21:40
不確定爲什麼這是有問題的?當你要求它讀取0字節時,你期望read()返回什麼? 1? -1? – stijn 2011-05-13 16:26:27
@BlackBear,還不如,如果有人知道構建一個測試,我寧願得到答案 - 即使最簡單的測試需要設置某些東西來連接,建立連接,然後嘗試看看會發生什麼。 – Eran 2011-05-13 16:33:56