2009-04-09 82 views
3

這是迭代套接字上的read的正確方法嗎?我很難讓這個工作正常。 data.size也是從套接字填充的unsigned int。它是正確的。 data.data是一個unsigned char *從套接字中迭代讀取()

if (data.size > 0) { 
    data.data = (unsigned char*)malloc(data.size); 
    memset(&data.data, 0, data.size); 
    int remainingSize = data.size; 
    unsigned char *iter = data.data; 
    int count = 0; 
    do { 
     count = read(connect_fd, iter, remainingSize); 
     iter += count; 
     remainingSize -= count; 
    } while (count > 0 && remainingSize > 0); 
} 
else { 
    data.data = 0; 
} 

在此先感謝。

回答

9

在開始將其添加到其他值之前,您需要檢查讀取的返回值。

當套接字報告EOF時,你會得到一個零,錯誤時會得到-1。請記住,對於套接字EOF與封閉不一樣。

3

把讀作的同時條件的一部分。

while((remainingSize > 0) && (count = read(connect_fd, iter, remainingSize)) > 0) 
{ 
    iter += count; 
    remainingSize -= count; 
} 

這樣如果失敗就立即停止循環。
使用讀作爲循環條件的一部分是非常普遍的模式,否則你需要檢查循環內部的代碼醜陋的狀態。

個人方面:
我會把整個上面的測試移動到一個單獨的函數爲可讀性,但你的milage可能非常。

另外使用malloc(和公司)將導致整個內存管理問題。我會使用std :: vector。當你修改它以開始拋出異常時,這也將證明代碼,現在它也將是異常安全的。

因此,假如你改變data.data有一個類型爲std ::的矢量<無符號的字符>然後

if (data.size > 0) 
{ 
    std::vector<unsigned char> buffer(data.size); 

    unsigned char *iter = &buffer[0]; 
    while(... read(connect_fd, iter, remainingSize)) 
    { 
     ..... 
    } 

    ... handle error as required 

    buffer.resize(buffer.size() - remainingSize); 
    data.data.swap(buffer); 
} 
3

請記住,閱讀()調用系統調用,從而可能阻止源,即使你使用非阻塞I/O,本身也是重量級的。我會建議儘量減少它們。

一個很好的方法是在C中使用非阻塞I/O併發出FIONREAD ioctl()以獲得等待的總數量一個給定的輪詢間隔(假設你正在使用某種同步I/O多路複用器,如select()),然後只是read()的次數來捕獲所有它,然後返回該時刻的函數直到下一個計時器打勾。