运维开发网

C语言 TCP套接字上的read()何时返回

运维开发网 https://www.qedev.com 2020-03-11 16:48 出处:网络 作者:运维开发网整理
有人可以解释一下,当我用来从TCP套接字获取数据的读取函数确实返回时? 我使用下面的代码从测量系统中读取数据.该系统提供频率为15 Hz的数据. READ_TIMEOUT_MS的值为200 此外,READ_BUFFER_SIZE的值为40000. 一切正常,但发生的事情是,read()每秒返回15次,读取1349字节. 通过阅读我希望的以下文档中的陷阱5,缓冲区完全填满: http://www.i
有人可以解释一下,当我用来从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;

我希望这个问题不重复,因为在我问之前我找了一个答案.

如果您需要更多信息,请与我们联系.

我怀疑你使用的是Linux. manpage for read says:

On success, the number of bytes read is returned (zero indicates end

of file), and the file position is advanced by this number. It is not

an error if this number is smaller than the number of bytes requested;

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

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

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

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

> https://www.lmax.com/blog/staff-blogs/2016/05/06/navigating-Linux-kernel-network-stack-receive-path/

> https://blog.cloudflare.com/how-to-achieve-low-latency/

> http://blog.packagecloud.io/eng/2016/06/22/monitoring-tuning-Linux-networking-stack-receiving-data

> http://syuu.dokukino.com/2013/05/Linux-kernel-features-for-high-speed.html

0

精彩评论

暂无评论...
验证码 换一张
取 消