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

C++ TCP套接字上的read()何时返回,c++,c,sockets,tcp,C++,C,Sockets,Tcp,有人能解释一下,我用来从TCP套接字获取数据的读取函数何时返回 我使用下面的代码从测量系统中读取数据。该系统以15 Hz的频率传输数据READ\u TIMEOUT\u MS的值为200 此外,READ\u BUFFER\u SIZE的值为40000。 所有这些都可以正常工作,但实际情况是,read()每秒返回15次1349字节读取 通过阅读以下文档中的陷阱5,我预计缓冲区已完全填满: 初始化: sock=socket(AF\u INET,sock\u STREAM,0); 如果(插座

有人能解释一下,我用来从TCP套接字获取数据的读取函数何时返回

我使用下面的代码从测量系统中读取数据。该系统以15 Hz的频率传输数据
READ\u TIMEOUT\u MS
的值为
200
此外,
READ\u BUFFER\u SIZE
的值为
40000
。 所有这些都可以正常工作,但实际情况是,
read()
每秒返回15次
1349
字节读取

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

初始化:

sock=socket(AF\u INET,sock\u STREAM,0);
如果(插座<0)
{
转到失败0;
}
服务器中的结构sockaddr_;
server.sin\u addr.s\u addr=inet\u addr(IPAddress);
server.sinu family=AF\u INET;
server.sin_port=htons(端口);
if(连接(sock,(struct sockaddr*)和服务器,sizeof(服务器)))
{
后藤1号;
}
结构时间值电视;
tv.tv\u sec=读取超时\u MS/1000;
tv.tv\u usec=(读取超时\u MS%1000)*1000;
if(setsockopt(sock,SOL_SOCKET,SO_RCVTIMEO,(char*)和tv,sizeof(struct timeval)))
{
后藤1号;
}
返回true;
故障1:
关闭(袜子);
sock=-1;
故障0:
返回false;
阅读:

unsigned char buf[READ_BUFFER_SIZE];
int len=读取(sock、buf、sizeof(buf));
if(len WriteToStream)(buf,len);
返回pData;
我希望这个问题不是重复的,因为在我提问之前我一直在寻找答案。
如果您需要更多信息,请告诉我。

我怀疑您正在使用Linux。以下内容:

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

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

从套接字读取时,您必须期望可以读取任意数量的字节。读取缓冲区中有任何内容或发生错误时,读取调用将立即返回。您无法预测或假设有多少字节可用

此外,由于操作系统被中断,调用可以在不读取任何内容的情况下返回。在调试或评测应用程序时经常会发生这种情况。您必须在应用程序层处理这种情况

当您希望具有高数据速率或低延迟时,完整的接收器路径异常复杂。内核和NIC实施了许多优化,例如将负载分散到内核上,增加局部性,并将处理卸载到NIC。以下是一些您可能会感兴趣的其他链接:


只要你的操作系统愿意,它就会返回。你必须准备好获得比你想要的更少的字节。陷阱5实际上暗示了这一点。图表显示读取1024个字节,但文本中提到它返回200个字节。你可能想寻找一个更容易控制的超时。@n.m:我理解操作系统的这种行为。但我很好奇为什么每次调用
read()
都会返回所需的字节数。我不明白你想说什么。如果你要求读取N个字节,你可以从0到N个字节。关于前面的句子有什么问题吗?谢谢你的回答!是的,我在Linux平台上工作。你说“只要读取缓冲区中有任何内容,对读取的调用就会返回。”这是否意味着
read()
返回的字节仅仅“匹配”"在我的情况下,有什么原因?@bushmills有很多网站描述了从NIC到应用程序的孔路径,例如,@bushmills是的,调用read可以获得任意数量的字节,最多可达提供的最大值。它可能是1。您必须在应用程序中实现自己的帧,例如,通过循环读取,直到收到预期的数量一条消息的字节数。我实现帧是为了获得测量系统发送的所有数据。既然一切正常,这不是一个问题。我只是想知道,为什么每次都能获得所需的字节数,即使这也不能保证。@bushmills我添加了更多的链接,这些链接描述了接收器部分和k的优化欧尼尔和尼克。
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;