从非阻塞c套接字读取大数据

时间:2016-01-06 22:47:06

标签: c sockets tcp

如何在C中读取非阻塞TCP套接字,但是以大块读取数据?

在我的实现中,结果总是为负,而errno等同于"资源暂时不可用"除非我们的数据大于' size'。

 result = read(fd, buffer, size);

当我们在C中读取非阻塞TCP套接字时,除非已收到我们从其请求的完整数据,否则它不会返回> = 0吗?

2 个答案:

答案 0 :(得分:3)

不正确,如果没有数据,它会返回< 0,并且会将errno设置为EAGAIN&#34; 资源暂时不可用&#34;或类似的错误值。 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(),则可能需要重置它。

答案 1 :(得分:1)

  

结果总是负数,而errno相当于&#34;资源暂时不可用&#34;除非我们的数据大于&#39; size&#39;。

除非套接字接收缓冲区中存在任何大小的数据。

  

当我们在C中读取非阻塞TCP套接字时,除非已收到我们从其请求的完整数据,否则它不会返回&gt; = 0吗?

没有。如果已到达流的末尾,它将返回零;如果套接字接收缓冲区中存在任何数据,则返回正整数。究竟有多少字节触发这是系统相关的(&#39;低水位标记&#39;)但它与您要求的字节数无关。

然而:

  • 在你遇到这种情况后继续阅读是不正确的:你应该调用select()或其中一种poll()/epoll()方法来告诉你套接字何时是下一个准备好阅读
  • 目前还不清楚为什么你要使用非阻塞模式,如果所有你需要做的就是循环和读取。我会使用阻止模式。