为 UDP 模拟 accept()(设置解复用 UDP 套接字的时间问题) [英] Emulating accept() for UDP (timing-issue in setting up demultiplexed UDP sockets)

查看:16
本文介绍了为 UDP 模拟 accept()(设置解复用 UDP 套接字的时间问题)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于具有长期连接的 UDP 服务器架构,一种架构是拥有一个侦听所有传入 UDP 流量的套接字,然后使用 connect() 为每个连接创建单独的套接字来设置远程地址.我的问题是,是否有可能像 accept() 对 TCP 所做的那样以原子方式执行此操作.

For an UDP server architecture that will have long-lived connections, one architecture is to have one socket that listens to all incoming UDP traffic, and then create separate sockets for each connection using connect() to set the remote address. My question is whether it is possible to do this atomically similar to what accept() does for TCP.

创建一个单独的套接字并使用 connect() 的原因是这样可以很容易地将数据包处理分散到多个线程中,并且也可以更容易地将套接字直接与所需的数据结构相关联加工.网络堆栈中的多路分离逻辑将传入的数据包路由到最具体的套接字.

The reason for creating a separate socket and using connect() is that this makes it easy to spread the packet-processing across multiple threads, and also make it easier to have the socket directly associated with the data structures that are needed for processing. The demultiplexing logic in the networking stack will route the incoming packets to the most specific socket.

现在我的问题基本上是当人们想像这样模拟 UDP 的 accept() 时会发生什么:

Now my question is basically what happens when one wants to emulate accept() for UDP like this:

  1. 将 select() 与包含 UDP 服务器套接字的 fd 集一起使用.

  1. Use select() with a fd-set that includes the UDP server-socket.

然后从 UDP server-socket 读取一个数据包.

Then read a packet from the UDP server-socket.

然后创建一个新的 UDP 套接字,然后将其连接()到远程地址

Then create a new UDP socket which is then connect()ed to the remote address

我使用包含两个套接字的 fd-set 调用 select().

I call select() with a fd-set that includes both sockets.

返回什么?

假设数据包在 1 到 3 之间到达操作系统.

given that a packet arrives to the OS somewhere between 1 and 3.

数据包会被解复用到 UDP 服务器套接字,还是会被解复用到在 3 中创建的更具体的套接字.也就是说,解复用发生在什么时候?当数据包到达时,还是必须好像"它到达第 4 点?

Will the packet be demultiplexed to the UDP server-socket, or will it be demultiplexed to the more specific socket created in 3. That is, at what point does demultiplexing take place? When the packet arrives, or must it happen "as if" it arrived at point 4?

如果上述方法不起作用,后续问题:最好的方法是什么?

Follow-up question in case the above does not work: What's the best way to do this?

推荐答案

这个问题是我自己在这里问的...

I found this question after asking it myself here...

UDP 服务器和连接的套接字

由于 UDP 可以使用 connect() 来指定对等地址,我想知道为什么不能使用 accept() 从服务器端有效地完成连接的 UDP 会话.它甚至可以将触发 accept() 的数据报(以及来自同一客户端的任何其他数据报)移动到新的描述符.

Since connect() is available for UDP to specify the peer address, I wonder why accept() wasn't made available to effectively complete the connected UDP session from the server side. It could even move the datagram (and any others from the same client) that triggered the accept() over to the new descriptor.

这将实现更好的服务器可扩展性(有关更多背景信息,请参阅 SO_REUSEPORT 背后的原理)以及可靠的 DTLS 身份验证.

This would enable better server scalability (see the rationale behind SO_REUSEPORT for more background), as well as reliable DTLS authentication.

这篇关于为 UDP 模拟 accept()(设置解复用 UDP 套接字的时间问题)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆