簡體   English   中英

從非阻塞c套接字讀取大數據

[英]read large data from nonblocking c socket

如何在C中讀取無阻塞的TCP套接字,但又要大塊讀取數據?

在我的實現中,結果始終為負,並且errno等效於“資源暫時不可用”,除非我們的數據大於“大小”。

 result = read(fd, buffer, size);

的確,當我們在C語言中讀取一個無阻塞的TCP套接字時,除非它收到了我們要求的完整數據,否則它將不會返回> = 0?

這是不正確的,沒有數據時它將返回< 0 ,並將errnoEAGAINResource Temporarily Unavailable ”或類似的錯誤值。 read()函數將讀取盡可能多的數據並返回,該值可能為負,指示錯誤(*或EAGAIN 資源暫時不可用於非阻塞套接字*),或者為正值,指示實際讀取了多少字節。

要檢查是否有要讀取的數據,請使用select() ,例如

struct timeval timeout = {1, 50000}; // Wait one 1.05 seconds
                                     // or a reasonable value
fd_set rdset;

FD_ZERO(&rdset);
FD_SET(fd, &rdset);

if (select(fd + 1, &rdset, NULL, NULL, &timeout) == 1) // Equals the number
{                                                      // of ready descriptors
    // Read data here
}
// No data ready, now it's your choice what to do

注意:在Linux上, select()更改timeout參數以反映剩余時間,因此,如果再次使用相同的參數調用select() ,則可能需要重置它。

結果始終為負,並且errno等同於“資源暫時不可用”,除非我們的數據大於“大小”。

除非套接字接收緩沖區中存在數據,否則任何大小。

的確,當我們在C語言中讀取一個無阻塞的TCP套接字時,除非它收到了我們要求的完整數據,否則它將不會返回> = 0?

否。如果已到達流的末尾,它將返回零;如果套接字接收緩沖區中存在任何數據,它將返回正整數。 究竟有多少字節觸發此操作取決於系統(“低水位標記”),但與您要求的字節數無關。

然而:

  • 遇到這種情況后,僅繼續讀取是不正確的:您應該調用select()poll()/epoll()方法之一來告訴您套接字何時下次准備讀取
  • 不清楚您為什么要使用非阻塞模式,如果您要做的就是循環讀取。 我會使用阻止模式。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM