2016-10-12 29 views
0

相對簡單的問題:在使用Linux非阻塞套接字進行recv()時,是否有一種方法可以先驗地確定可以接收多少數據?Linux非阻塞套接字:阻塞之前可以讀取多少數據?

看來我總是會做一個額外的recv()調用來確定我已經排空了所有數據。

+2

如果你能得到這些信息,在你採取行動之前它已經陳舊了...... –

+1

你是什麼意思'阻塞'之前?這是一個非阻塞的套接字。它不會阻止。你可以直接調用'recv()'直到發生EAGAIN/EWOULDBLOCK。不清楚你在問什麼。 – EJP

回答

2

您可以使用ioctl()FIONREAD來獲取套接字緩衝區中未讀字節的數量。

但是,這也可能是雙重系統調用,並且在您撥打recv()之前,仍然無法保證有更多數據未到達。

但有一種更簡單的方法 - 您可以撥打recv(),它會返回實際讀取的字節數。如果實際讀取的字節數與請求的緩衝區大小相同,則只需重複調用。即使您不重複該呼叫,也會返回下一個select()調用,以確定是否還有更多可供讀取的數據。

+0

我很確定recv(像read)可以自由地給你儘可能多的字節,因爲它返回小於你的緩衝區大小並不意味着它沒有數據。 – rivenmyst137

+0

@ rivenmyst137:Posix可能不保證這一點,但我沒有看到任何其他行爲的實現。無論如何,所描述的'recv()'和'select()'的組合在任何情況下都可以工作。 –

0

您可以使用recv中的MSG_PEEK標誌來確定要從套接字緩衝區讀取的當前字節數。如果應用程序在可以處理數據之前等待確定的字節數,則它可以依賴於MSG_PEEK。數據不會從套接字緩衝區中刪除。但是,如果您在沒有MSG_PEEK的情況下閱讀,則ret將是相同的值。

ret = recv(sd, buf, MAX_CALL_DATA_SIZE, MSG_PEEK);

這種方法會導致額外的系統調用,直到的字節數的應用需求是套接字緩衝區。另外,在實際將數據讀入應用程序時,並不保證會有更多的字節到達。