处理在同一端点上侦听的多个 UDP 套接字

问题描述 投票:0回答:1

我一直在(大致)遵循一些示例代码here编写可以处理多个客户端的DTLS服务器。在这个例子中,效果很好(我尝试过),服务器监听

INADDR_ANY
和端口
0

fd = socket(server_addr.ss.ss_family, SOCK_DGRAM, 0);
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const void*) &on, (socklen_t) sizeof(on));
bind(fd, (const struct sockaddr *) &server_addr, sizeof(struct sockaddr_in))

收到 DGRAM 后,服务器通过 OpenSSL 方法运行它以生成 cookie 并验证客户端“实际上”位于他们所说的地址。完成后,服务器创建一个绑定到同一端点的新套接字,并对新客户端的端点执行connect()操作。



bind(fd, (const struct sockaddr *) &pinfo->server_addr, sizeof(struct sockaddr_in))
connect(fd, (struct sockaddr *) &pinfo->client_addr, sizeof(struct sockaddr_in))

因此此时,有 2 个 UDP 套接字绑定到
相同的 IP 地址和端口

。其中一个是 connect()ed 的,另一个只是绑定的。


我尝试做同样的事情(在 C# 中):

_sock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); _sock.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); _sock.Bind(localEp); var clientEndpoint = await DtlsListenAsync(ssl, _sock); var clientSock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); clientSock.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); clientSock.Bind(_localEp); clientSock.Connect(clientEndpoint);

请记住,为了简洁起见,我已经删除了大部分代码。

此时,运行

my

应用程序惨败。似乎为客户端创建的套接字永远不会收到消息。基本上任何对 await clientSock.ReceiveAsync() 的调用都会无限期挂起。


但是

,如果我调试并单步执行,代码就可以工作。这让我相信这是套接字之间的“竞赛”。基本上,可以在下一个 DGRAM 进入并发送到original套接字之前创建、绑定和连接客户端套接字吗? 据我所知,UDP 套接字在

score

系统上工作。内核根据给定 DGRAM 的路由具体程度来计算分数,并将其发送到得分最高的套接字。所以,在我看来,我的服务器应该和示例一样工作......但事实并非如此。 所以我并不是真的在问我的

code

本身是否正确,但我想知道我想做的事情是否有意义。另外,如果还有什么我没有考虑到的因素。套接字的行为是否像我提到的那样? 如果此方法不起作用,我的替代方案是使用单个套接字并维护端点的哈希表,并将数据发送到适当的客户端。但是说实话,我真的很喜欢利用套接字来执行以下操作的想法对我来说“举重”。

c# c sockets udp dtls
1个回答
0
投票

© www.soinside.com 2019 - 2024. All rights reserved.