C++异步网络编程

发布于 2024-10-04 16:22:10 字数 712 浏览 6 评论 0原文

我有一些简单的问题,我有一个客户端服务器应用程序和在线发送的数据。

我希望能够恢复数据并正确处理它。

struct T1
{
   int id;
   int foo;
};

struct T2
{
  int id;
  char foo;
  int bar;
};

让我们采用这些结构,它们在网络上发送,前面有一个 int,它将告诉后面是 T1 还是 T2。 如果客户端向我发送 T1,然后向我发送 T2,我是否可以保证可以使用 asio::ip::tcp::socket.async_read() 读取完整结构? 我想设置一个处理程序来处理单个结构,但是如果我无法读取单个 async_read() 中的所有内容会发生什么?

异步操作将 继续,直到出现以下情况之一 条件成立:

  • 提供的缓冲区已满。也就是说,传输的字节数等于缓冲区大小的总和。
  • 发生错误。

无法读取的数据会被丢弃吗?它会触发另一个 async_read 吗? 而且,如果我的客户端按顺序向我发送 ID+结构,我是否可以保证 async_read 只会获得一个 ID+结构?或者操作系统可以优化一些东西并将它们放在同一个 paquet 中吗? 正如您可能已经看到的,我有点困惑,我想在设计服务器/客户端应用程序时做出正确的决定,任何帮助将不胜感激。

谢谢。

I have some simple questions, I have a client-server application and data sent on the wire.

I'd like to be able to recover the data and handle it properly.

struct T1
{
   int id;
   int foo;
};

struct T2
{
  int id;
  char foo;
  int bar;
};

Let's take these structures, they are sent on the network preceded by an int which will tell if either T1 or T2 follows.
If the client sends me T1, then sends me T2, do I have the assurance that I can read a full structure with asio::ip::tcp::socket.async_read() ?
I'd like to set up a handler which will handle a single struct, however what will happen if I'm unable to read everything in a single async_read() ?

The asynchronous operation will
continue until one of the following
conditions is true:

  • The supplied buffers are full. That is, the bytes transferred is equal to the sum of the buffer sizes.
  • An error occurred.

Will it discard the data that cannot be read ? will it trigger another async_read ?
And, am I assured that an async_read will only get one ID+structure if my client sends me sequentially the ID+structure ? Or may the OS optimize things and put them both in the same paquet ?
As you may have seen, I'm a little confused, I'd like to make the right decisions when designing a server/client application, any help will be appreciated.

Thank you.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

一杯敬自由 2024-10-11 16:22:10

编辑:感谢@timo 指出错误。 async_read 在读取整个结构之前不会完成,因此您不需要循环。否则,我的答案是一样的。无论 TCP 协议如何分解或合并数据,都不会丢失任何内容。

如果 TCP 缓冲区中没有足够的数据来填充输入缓冲区,则读取将简单地获取可用的数据,并报告获取的字节数。接下来会发生什么取决于你。您可能在获取的字节中有足够的数据来决定您不想继续,因此 asio 不做任何假设。如果您没有读取足够的字节来组成完整的结构,则启动进一步的 async_read,重复该过程,直到您有足够的字节或某些东西消失。

我不确定你所说的“无法阅读所有内容”是什么意思。我想到了两种可能的含义:

  1. 可供读取的数据量无法填充结构。在这种情况下,您只需执行另一个 read_async 来等待更多数据到达。
  2. 该结构不会吸收所有已到达的数据。 TCP 堆栈将简单地缓冲未读数据,直到您有时间读取它。

EDIT: Thanks to @timo for pointing out a mistake. async_read won't complete until an entire struct is read, so you don't need to loop. Otherwise, my answer is the same. Nothing will be lost, regardless of how the TCP protocol breaks up or coalesces the data.

If there isn't enough data in the TCP buffers to fill your input buffer, the read will simply fetch whatever is available, and report the number of bytes fetched. What happens next is up to you. You might have enough data in the fetched bytes to decide you don't want to continue, so asio makes no assumptions. If you haven't read enough bytes to comprise a complete structure, then initiate a further async_read, repeating the process until you have enough bytes or something dies.

I'm not sure what you mean by, "unable to read everything." two possible meanings come to mind:

  1. The amount of data that's available to read doesn't fill a struct. In this case, you simply do another read_async to wait for more data to arrive.
  2. The struct doesn't absorb all that data that has arrived. The TCP stack will simply buffer unread data until you get around to reading it.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文