Boost asio udp 读取优化问题

Boost asio udp read optimization questions

我正在处理的服务器应用程序通过 udp 从我的客户端应用程序接收数据。

服务器必须异步接收udp数据。似乎有两种通用方法可以完成此操作。

方法一:

boost::array<char, 65000> recv_buffer;
socket.async_receive_from(boost::asio::buffer(recv_buffer), senderEndpoint, handler);

方法二(来自Variable-size buffer for receiving UDP packets):

socket.async_receive(boost::asio::null_buffers(), receive_handler);

// in the handler code
unsigned int available = socket.available();
buffer = resize_buffer_if_needed(available);
unsigned int packetSize = socket.receive_from(boost::asio::buffer(buffer, available), senderEndpoint, 0, ec);

请帮我评估一下哪种方法可能更适合我的需求。问候。

问题 1:

从提到的 post 来看,方法 2 似乎效率低下,因为它导致 asio 先将数据存储到内部缓冲区,然后再将其复制到我的缓冲区。这是正确的吗?

问题 2:

客户端绝不会在对 socket.send_to(). 的单次调用中发送超过 64K 的数据。鉴于此,方法 1 总是更好的选择吗?

问题 3:

我需要提供一种方法来减少对我的服务器的攻击。我正在考虑使用前两个字节作为魔术键。这个想法是,如果前两个字节不是预期的魔术键,我会忽略一条消息。鉴于此,使用方法2更好吗?

问题 4:

在我的设计中,接下来的四个字节将是后面二进制数据的实际大小。但是,鉴于 socket.available() 已经给出了长度,看来我真的不必发送此信息。仅仅依靠 socket.available() 长度可以吗?

  1. 不,它不会先将其存储在临时缓冲区中。它使用 FIONREAD ioctl 查看内核的 IP 堆栈缓冲区中的内容。

  2. 我会说是的,因为代码更简单而且不需要做任何动态分配

  3. 不,因为您仍然会一次接收整个数据包,这是数据报套接字的特性。只需保护最大缓冲区大小并避免解析不受信任的数据。 "magic number" 几乎没有任何保护。攻击者适应起来非常简单(只有 65536 种可能的组合)。最好有一个 HMAC-sgin(或类似的)来验证数据包。

  4. 它仍然是UDP,所以几乎没有任何增益分批接收(内核没有所以它只是来回增加更多CPU负载以获得相同的延迟) .

    还有:

    Q. In my design, the next four bytes were going to be the actual size of the binary data that follows

    首先要注意身份验证。不要解析不受信任的数据。参见 Colin PercivalEncrypt-then-MAC