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

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

问题描述

对于具有长期连接的UDP服务器体系结构,一种体系结构是具有一个侦听所有传入UDP流量的套接字,然后使用connect()为每个连接创建单独的套接字以设置远程地址.我的问题是,是否可以像原子接受()对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. 对带有UDP服务器套接字的fd集使用select().

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

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

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集合的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服务器和连接的套接字

由于connect()可用于UDP指定对等地址,所以我想知道为什么没有提供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天全站免登陆