我必须从套接字读取未知长度的数据。我需要等待特定的字符序列才能停止阅读。
一次只读一个字节是个好主意吗?最大长度是4096.我知道从插座读取应该尽可能大,以便阅读,但在我的情况下,当最大长度不长时,这是一个很好的解决方案吗?
这种阅读有什么后果?
缓冲区溢出?
答案 0 :(得分:3)
首先,答案很大程度上取决于套接字的类型。
如果这是一个数据报套接字(UDP),则答案是响亮的否。从数据报套接字中只读取一个字节会导致丢失重要信息。读取的大小应该(至少)对应于发送的大小。
假设这是一个蒸汽插槽(TCP),一次只读取一个字节就没有语义上的危害。无论哪种方式,结果都是正确的。这并不是说这是一个好主意。每次调用read
都需要切换到内核模式并执行一系列操作。无论您是检索一个字节的批次,这些都是同样昂贵的。因此,强烈建议您在性能方面每次执行更大的读取操作。
解决您的困境的方法是使用缓冲IO。创建或使用预先存在的适配器,该适配器将执行大read
个以将数据导入用户空间缓冲区,然后您可以在最佳的任何块大小套件中从此缓冲区中选择字节。 / p>
答案 1 :(得分:0)
一次只读一个字节是个好主意吗?最大长度为4096
不,这不是一个好主意,尤其是在使用阻止read()
时。
您可以使用固定大小的本地缓冲区,以便读取最大数据:
std::array<uint8_t,4096> buffer;
并使用read()
的返回值实际可用的数据
std::vector<uint8_t> message;
int bytes_read = 0;
do {
bytes_read = read(sockfd,buffer.data(),buffer.size());
if(bytes_read >= 0) {
// inspect the received data for the stop sequence
if( /* stop sequence detected */ ) {
break;
}
// collect data
message.insert(message.end(),&buffer.begin(),&buffer[bytes_read]);
}
} while(bytes_read > 0);