模拟UDP的accept()(设置解复用的UDP套接字时的时间问题)

时间:2009-06-30 16:10:51

标签: select udp

对于具有长期连接的UDP服务器体系结构,一种体系结构是拥有一个侦听所有传入UDP流量的套接字,然后使用connect()为每个连接创建单独的套接字以设置远程地址。我的问题是,是否有可能在原子上类似于accept()对TCP的作用。

创建一个单独的套接字并使用connect()的原因是,这使得在多个线程之间传播数据包处理变得容易,并且还使得套接字更容易直接与数据结构相关联。处理。 网络堆栈中的解复用逻辑将传入的数据包路由到最特定的套接字。

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

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

  2. 然后从UDP服务器套接字读取数据包。

  3. 然后创建一个新的UDP套接字,然后connect()ed到远程地址

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

  5. 返回了什么?

  6. 假设数据包到达操作系统1到3之间的某个位置。

    数据包是否会被多路分解到UDP服务器套接字,还是会被解复用到3中创建的更具体的套接字。也就是说,在什么时候进行多路分解?当数据包到达时,或者必须“好像”它到达第4点?

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

3 个答案:

答案 0 :(得分:0)

这不起作用。
你有两个简单的选择。

  1. 创建一个多线程程序,其中“root”线程侦听UDP套接字,并根据源将“接收”数据包“分派”到正确的线程。这是因为您希望按源隔离处理。

    • 扩展协议,以便源接受某个固定端口上的传入连接,然后继续协议通信。在这种情况下,您可以将源请求放在标准UDP端口(您选择的)上,然后您的端将从新的UDP套接字响应到源的UDP端口。这样,您就可以从末端向后发起到每个源的已知UDP端口的新UDP路径。这样你就可以得到不同的UDP套接字。

答案 1 :(得分:0)

我看到这个讨论是从2009年开始的,但是因为它在我搜索时不断弹出,我想我应该分享我的方法。两者都得到一些反馈,因为我很好奇问题的作者如何解决问题。

我选择模拟UDP-accept的方式是nik答案中的第一和第二组合。我有一个根线程,它侦听给定的套接字。为简单起见,我选择使用TCP,但将此套接字更改为UDP并不是很难。当客户端想要使用UDP“连接”到我的服务器时,它首先连接到TCP套接字并请求新连接。

然后,根线程通过创建UDP套接字,将其绑定到本地接口,连接并设置数据结构来继续。然后将此文件描述符传递给负责连接的线程。新UDP套接字的IP /端口信息将传递回客户端,从而创建新的UDP套接字并将数据发送到提供的IP /端口。

这种方法适合我的使用,但设置流程的其他步骤会带来开销。在某些情况下,这种开销可能是不可接受的。

答案 2 :(得分:0)

我在这里自己问过之后发现了这个问题...

UDP server and connected sockets

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

这将实现更好的服务器可伸缩性(有关更多背景信息,请参见SO_REUSEPORT的基本原理),以及可靠的DTLS身份验证。