繁体   English   中英

有什么方法可以检查在 C 的缓冲区中写入了多少数据/字节

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

有什么方法可以检查在确切的时刻在缓冲区中写入了多少字节? 我想使用socket.send()动态设置我通过套接字发送的数据量。 现在我有问题,假设我的文件是 200KB,我的缓冲区设置为 24KB,所以我需要发送 9 个包,我的 output 文件是 216KB 大,而不是 200KB 作为输入。 有没有办法处理这些空字节?

socket.send我不知道。 我假设您的意思是在某些socket(7)上使用send(2 ) 。

在许多情况下(想想一些tcp(7)流量通过几个 Wifi 路由器),数据包可能会被分段 因此,一侧的给定send(2)可能对应于接收侧的多个recv(2) ,反之亦然。

然后你需要以某种方式管理你的数据包数据(例如计数和缓冲发出的数据,以及接收的数据)。 在实践中,您需要一些关于它们的文档化约定。 HTTPSMTPJSONRPCONCRPCMQTT可能是鼓舞人心的。

您会找到可能有用的库。 例如libcurlWtQtPOCOlibonion 它们是开源的,因此您可以研究它们的源代码。

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 githubgitlab

您将问题标记为CC++但它们是非常不同的语言。 有关更多信息,请参阅此参考

顺便说一句, Clang static 分析仪应该会有所帮助。 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)

有什么方法可以检查在 C 的缓冲区中写入了多少数据/字节

是的,因为send(2)write(2) (以及recv(2)read(2) )都在成功时返回字节数。

您的事件循环将处理它们(计数字节、管理缓冲区)并使用poll(2)或其他一些多路复用系统调用。 在这种情况下,您可以找到有用的库( libevlibevent等...)

另请注意,2020 年我们到处都有 UTF-8 因此,即使对于文本输入,某些字母(如俄语 Ы 或法语 à 或您居住的城市波兹南的最后一个字母......)可能需要超过一个字节。 当您发送文本信息时,这会增加代码的复杂性。

最好的办法是自己计算这些字节数,因为您总是知道要写入多少字节。

如果您有 200KB 要发送,并且一次可以发送 24KB,那么它只是(在伪代码中):

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

简单的。

(实际上,您可能应该使用一些无符号类型,例如std::size_t ,而不是int ,除非您的send在错误时返回一些负值。)

bytesToSend是这里的关键。 您可能不想在最后一次迭代中发送“完整”块。 这就是您额外的 16KB 的来源:您的输入不是块大小的精确倍数。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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