对于具有长期连接的UDP服务器体系结构,一种体系结构是拥有一个侦听所有传入UDP流量的套接字,然后使用connect()为每个连接创建单独的套接字以设置远程地址。我的问题是,是否有可能在原子上类似于accept()对TCP的作用。
创建一个单独的套接字并使用connect()的原因是,这使得在多个线程之间传播数据包处理变得容易,并且还使得套接字更容易直接与数据结构相关联。处理。 网络堆栈中的解复用逻辑将传入的数据包路由到最特定的套接字。
现在我的问题基本上是当人们想要为这样的UDP模拟accept()时会发生什么:
将select()与包含UDP服务器套接字的fd-set一起使用。
然后从UDP服务器套接字读取数据包。
然后创建一个新的UDP套接字,然后connect()ed到远程地址
我用包含两个套接字的fd-set调用select()。
返回了什么?
假设数据包到达操作系统1到3之间的某个位置。
数据包是否会被多路分解到UDP服务器套接字,还是会被解复用到3中创建的更具体的套接字。也就是说,在什么时候进行多路分解?当数据包到达时,或者必须“好像”它到达第4点?
如果以上情况不起作用的后续问题:最好的方法是什么?
答案 0 :(得分:0)
这不起作用。
你有两个简单的选择。
创建一个多线程程序,其中“root”线程侦听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身份验证。