有人可以解释一下,当我用来从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;
我希望这个问题不重复,因为在我问之前我搜索了一个答案。 如果您需要更多信息,请与我们联系。
答案 0 :(得分:1)
我怀疑您使用的是Linux。 manpage for read says:
成功时,返回读取的字节数(零表示结束 (文件),文件位置按此编号前进。它不是 如果此数字小于请求的字节数,则会出错;
TCP套接字模拟字节流,而不是块或面向消息的协议。如果应用程序缓冲区中有任何可用数据,则在套接字上调用read将返回。原则上,数据到达网卡,然后传输到内核空间,由内核和网络堆栈处理。最后,read
系统调用从内核空间获取数据并将其传输到用户空间。
从套接字读取时,您需要可以读取任意数量的字节。只要读缓冲区中有任何内容或发生错误,就会立即调用read。您无法预测或假设可用的字节数。
此外,由于操作系统已被中断,因此无需读取任何内容即可返回调用。在调试或配置应用程序时,这种情况经常发生。您必须在应用程序层中处理此问题。
当您想要高数据速率或低延迟时,完整的接收器路径非常复杂。内核和NIC实现了许多优化,例如:在核心上扩展负载,增加局域性并卸载到NIC的处理。以下是一些您可能感兴趣的其他链接: