我正在构建一个p2p应用程序,其中每个对等方都可以维持与多个其他对等方的连接。
使用TCP维护连接很容易。我有一台服务器在每个节点上的特定端口上侦听。每当peerA
要连接到peerB
时,它都会创建一个套接字并向peerB
的监听端口进行连接调用。这将创建一个新的套接字,对等双方都可以在其上进行所有后续对话。
我想在UDP中模拟相同的工作流程概念。与this问题类似的东西根据我发现的在UDP上与多个对等方进行对话的传统方式是,每个对等方都在预定义的端口上进行监听。每个sendTo调用都指定了我们要连接到接收方并在接收方连接的对等方的ip和端口,我们使用recvFrom来根据它来自哪个对等方来处理它(例如,将msg传递到处理来自该特定对象的消息的线程同行)。
但是,我想知道是否有任何方法可以做到而无需在接收器处进行多路分解。我发现SO_REUSEPORT标志可用于实现此http://man7.org/linux/man-pages/man7/socket.7.html
https://lwn.net/Articles/542629/。
基本上,SO_REUSEPORT允许在同一端口上的多个套接字调用绑定。因此,我像以前一样绑定服务器端口。但是,当我从新的对等方获得连接时,我将新的套接字绑定到相同的端口,并在发送者的地址上调用connect。然后,我将此新套接字传递给一个线程,该线程侦听来自发送方的消息。
makeListeningSocket ip port = do
sock <- socket ip port
setSocketOption sock ReusePort 1
bind sock
return sock
runUDPServer sock = do
(receivedMessage, peerAddr) <- recvFrom sock 4096
newSock <- makeListeningSocket "0.0.0.0" 3001
connect newSock peerAddr
async (readMessagesFromSock newSock)
runUDPServer sock
我能够使这种方法起作用。但是,似乎并未在考虑此特定用例的情况下创建SO_REUSEPORT选项。所以我的问题是,以我看不见的方式使用SO_REUSEPORT有什么可怕的错误吗?有更好的方法吗?