2009-04-09 40 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()的次数来捕获所有它,然后返回该时刻的函数直到下一个计时器打勾。