我正在监视select
循环中管道的读取端,并在有数据时使用read
从其读取。我一直期望通过管道的某种数据格式(出于示例的原因)是struct packet_t
类型。一旦select
调用发出信号,我的初始代码就对文件描述符执行了以下操作:
int
read_packet(int fd)
{
struct packet_t pkt;
int read_bytes = read(fd, &pkt, sizeof(pkt));
if (bytes_read <= 0)
{
/* handle some sort of error */
return -E_SOCK;
}
else if (bytes_read < sizeof(pkt))
{
/* return bad message format */
return -E_BADMSG;
}
/* do something with the packet */
return E_OK;
}
很明显,以上操作无法满足我的预期,因为可能是read
调用返回的字节少于sizeof(pkt)
的字节,原因仅是有些延迟,后来是其余字节也将被交付,完成包装。但是,我的代码假定,如果在第一次调用read
时未收到完整的数据包,则它一定是传输错误,所有后续数据包都将被视为坏数据。
要解决此问题,我需要缓冲读取操作,即读入单独的缓冲区,并且仅在接收到的字节数至少为sizeof(pkt)
时,才将缓冲区内容解释为数据包。
我的问题是:是否有c ++类或技术可以很好地实现缓冲读取?例如,我可以构造一个类mybuffer
,该类保存已读取的字节以及命中时的字节。一个阈值,它调用一个回调,使我可以读取数据包。但是,我不想重新发明轮子,而是问标准库(例如,使用iostream
或其他{{1 }}。
感谢您的支持!