什么时候TCP套接字上的read()返回

时间:2016-08-30 06:07:16

标签: c++ c sockets tcp

有人可以解释一下,当我用来从TCP套接字获取数据的读取函数确实返回时?

我使用下面的代码从测量系统中读取数据。该系统提供频率为15 Hz的数据。 READ_TIMEOUT_MS的值为200 此外,READ_BUFFER_SIZE的值为40000。 一切正常,但发生的情况是,read()每秒返回15次,读取1349个字节。

通过阅读以下文档中的陷阱5,我希望缓冲区完全填满:

http://www.ibm.com/developerworks/library/l-sockpit/

初​​始化:

sock=socket(AF_INET, SOCK_STREAM, 0);
if (socket < 0)
{
    goto fail0;
}

struct sockaddr_in server;
server.sin_addr.s_addr = inet_addr(IPAddress);
server.sin_family = AF_INET;
server.sin_port = htons(Port);
if (connect(sock,(struct sockaddr *)&server, sizeof(server)))
{
    goto fail1;
}

struct timeval tv;
tv.tv_sec = READ_TIMEOUT_MS / 1000;
tv.tv_usec = (READ_TIMEOUT_MS % 1000) * 1000;
if (setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(struct timeval)))
{
    goto fail1;
}

return true;

fail1:
    close(sock);
    sock = -1;
fail0:
    return false;

读:

unsigned char buf[READ_BUFFER_SIZE];
int len = read(sock, buf, sizeof(buf));
if (len <= 0)
{
    return NULL;
}

CBinaryDataStream* pData = new CBinaryDataStream(len);
pData->WriteToStream(buf, len);
return pData;

我希望这个问题不重复,因为在我问之前我搜索了一个答案。 如果您需要更多信息,请与我们联系。

1 个答案:

答案 0 :(得分:1)

我怀疑您使用的是Linux。 manpage for read says

  

成功时,返回读取的字节数(零表示结束   (文件),文件位置按此编号前进。它不是   如果此数字小于请求的字节数,则会出错;

TCP套接字模拟字节流,而不是块或面向消息的协议。如果应用程序缓冲区中有任何可用数据,则在套接字上调用read将返回。原则上,数据到达网卡,然后传输到内核空间,由内核和网络堆栈处理。最后,read系统调用从内核空间获取数据并将其传输到用户空间。

从套接字读取时,您需要可以读取任意数量的字节。只要读缓冲区中有任何内容或发生错误,就会立即调用read。您无法预测或假设可用的字节数。

此外,由于操作系统已被中断,因此无需读取任何内容即可返回调用。在调试或配置应用程序时,这种情况经常发生。您必须在应用程序层中处理此问题。

当您想要高数据速率或低延迟时,完整的接收器路径非常复杂。内核和NIC实现了许多优化,例如:在核心上扩展负载,增加局域性并卸载到NIC的处理。以下是一些您可能感兴趣的其他链接: