2015-03-25 83 views
0

我們有recvfunction它正在接收特定數量的字節。我需要編寫一個返回指向char的函數,其中包含全部數據,由服務器響應。如何接收服務器發送的所有數據?

char* receive_all() 
{ 
    //Don't know how... 
} 

的事情是我無法知道服務器響應什麼字節量,直到我收到的是,所以我不能創建一個適當大小的數組像

char* buf = new char[1000]; //Maybe the server's response have more than 1000 bytes 
+0

你使用UDP還是TCP? – mpromonet 2015-03-25 08:03:29

+0

@mpromonet它有什麼關係嗎? – user3663882 2015-03-25 08:05:39

+0

使用TCP,您需要多次調用recv以確保獲得發送的唯一發送內容。 – mpromonet 2015-03-25 08:17:47

回答

0
int receive(int sockfd, void *buf, size_t len, int flags) 
{ 
    size_t toread = len; 
    char *bufptr = (char*) buf; 

    while (toread > 0) 
    { 
     ssize_t rsz = recv(sockfd, bufptr, toread, flags); 
     if (rsz <= 0) 
      return rsz; /* Error or other end closed connection */ 

     toread -= rsz; /* Read less next time */ 
     bufptr += rsz; /* Next buffer position to read into */ 
    } 

    return len; 
} 
+0

好吧,傳遞給函數shoudl的buf大小應該是多少? – user3663882 2015-03-25 07:10:20

+0

您的緩衝區大小。緩衝區被定義在功能範圍之外。 – 2015-03-25 07:15:02

+0

@AndrewKomiagin我想你誤解了OP的想法。 – immibis 2015-03-25 07:17:36

0

malloc和realloc函數可用於動態分配和重新分配緩衝區。以防萬一數據可能變得非常巨大,那就使用一個簡單的鏈表。

struct node { 
    char buf[4096]; 
    struct node *next; 
}; 

爲了更有效地調整您的緩衝區大小與服務器的頁面大小,通常它是4096字節。所以你可以做什麼是創建一個新的節點,每次接收到數據時

ssize_t rsz = recv(sockfd,bufptr,toread,flags);

最後讀取整個數據遍歷鏈表。

-1

您可以通過ioctl(fd,FIONREAD,&bytes_available)獲得當前掛起的大小。由於您將問題標記爲C++,只需使用std::vector<char>即可。它有一個.resize(bytes_available)方法。

當然,數據包是異步接收的,所以bytes_available的值應該理解爲最小值。