简体   繁体   中英

Reading one byte vs multiple bytes from a socket

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?

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.

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);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM