简体   繁体   中英

Is there any way to check how much data/bytes is written in buffer in C

is there any way to check how many bytes are written in a buffer at the exact moment? I would like to dynamically set how much data I send via socket using socket.send() . Now I have problem, lets say that my file is 200KB and my buffer is set to 24KB so I need to send 9 packages and my output file is 216KB big and not 200KB as input. Is there any way to handle these empty bytes?

socket.send is unknown to me. I assume you mean using send(2) on some socket(7) .

In many cases (think of some tcp(7) traffic going thru several Wifi routers), the packets could be fragmented . So a given send(2) on one side could correspond to several recv(2) on the receiving side and vice versa.

Then you need to manage somehow your packet data (eg count and buffer the emitted data, and the received one). In practice, you'll need some documented conventions about them. HTTP or SMTP or JSONRPC or ONCRPC or MQTT could be inspirational.

You'l find libraries which could be helpful. Eg libcurl , Wt , Qt , POCO , libonion . They are open source, so you are allowed to study their source code.

You could also study the source code of well known open source servers, such as lighttpd , postfix , etc... or take inspiration from other open source projects coded in C++, including The Clang static analyzer , RefPerSys or fish or many others on github or gitlab .

You tagged your question both C and C++ but these are very different languages. See this reference for more.

BTW, the Clang static analyzer should be helpful. If you compile your C++ code with a recent GCC , be sure to enable all warnings and debug info, so compile with g++ -Wall -Wextra -g (and later use the GDB debugger)

Is there any way to check how much data/bytes is written in buffer in C

Yes, since both send(2) and write(2) (and also recv(2) and read(2) ) are returning a byte count on success.

Your event loop will handle them (counting bytes, managing buffers) and use poll(2) or some other multiplexing syscall. You could find libraries helpful in that case ( libev , libevent , etc...)

Be also aware than in 2020 we have UTF-8 everywhere . So even for textual input, some letters (like the Russian Ы or the French à or the last letter of the city Poznań you are living in...) may take more than one byte. When you send textual information, this adds complexity to your code.

The best thing to do is to keep a count of these bytes yourself, since you always know how many bytes you're writing.

If you have 200KB to send, and you can send 24KB at a time, then it's just (in pseudocode):

const int chunkSize = 24*1024;
const int inputSize = 200*1024;

char input[inputSize];   // N.B. VLAs not actually valid C++; this is pseudo-code
int bytesSent = 0;

while (true)
{
   const int bytesRemaining = inputSize - bytesSent;
   const int bytesToSend = std::min(chunkSize, bytesRemaining);
   
   if (bytesToSend == 0)
   {
      // Done!
      break;
   }
   
   const int bytesWritten = send(&input[bytesSent], bytesToSend);
   
   if (bytesWritten == 0)  // I'm assuming 0 written means error; adjust for your API
   {
      // Error! Handle it.
      break;
   }
   
   bytesSent += bytesWritten;
   
   if (bytesSent > inputSize)
   {
      // Something went horribly wrong
      break;
   }
}

Easy.

(In reality you should possibly use some unsigned type like std::size_t , not int , unless your send returns some negative value on error.)

bytesToSend is the key here. You may not want to send a "full" chunk in the last iteration. That's where your extra 16KB came from: your input wasn't an exact multiple of the chunk size.

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