Reputation: 523
I have to read data of an unknown length from a socket. I need to wait for a particular sequence of characters to stop reading.
Is it good idea to read only one byte at a time? Maximum length is 4096. I know that reading from a socket should be realized with as large a size to read, as possible, but in my situation, when max length isn't long is it good solution?
What are the consequences of such a reading?
A buffer overflow?
Upvotes: 3
Views: 2623
Reputation: 1
Is it good idea to read only one byte at once? Maximum length is 4096
No, that's not a good idea, especially not when using a blocking read()
.
You can use a local buffer with a fixed size that allows to read up for the maximum data:
std::array<uint8_t,4096> buffer;
and use the return value of read()
how much data was actually available
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);
Upvotes: 1
Reputation: 8583
First of all, the answer greatly depends on the type of socket.
If this is a datagram socket (UDP), then the answer is a resounding no. Reading just one byte from a datagram socket will cause you lose important information. The sizes of the reads should correspond (at least) to the sizes of the sends.
Assuming this is a steam socket (TCP), there is no semantic harm in reading just one byte at a time. The result will be correct either way. Which is not to say this is a good idea. Each call to read
requires switching to kernel mode and performing a bunch of operations. These are equally costly whether you are retrieving one byte of lots. As such, it is highly recommended, performance wise, that you perform larger reads each time.
The solution to your predicament is to use buffered IO. Either create, or use a pre-existing, adapter that will perform large read
s to get the data into a user space buffer, and then you can pick the bytes from this buffer in whatever chunk sizes suites you best.
Upvotes: 7