重用UDP中的端口号

时间:2010-09-20 21:38:46

标签: linux sockets

在ASIO中,是否可以创建另一个与另一个套接字具有相同源端口的套接字?

我的UDP服务器应用程序使用端口3000调用receive_from。它传递数据包 关闭将发送响应的工作线程(当前使用动态源端口)。

另一个线程中的套接字是这样创建的:

udp::socket sock2(io_service, udp::endpoint(udp::v4(), 0));

使用与原始数据包一起保存的sender_endpoint响应原始请求。

我希望能够做的是使用与服务器正在侦听的源端口相同的源端口来响应客户端。但我看不出如何做到这一点。如果我尝试说地址在使用中,我会得到一个例外。有可能做我要问的事吗?我想要的原因是如果我使用动态端口,这意味着客户端需要在Windows中添加特殊的防火墙规则以允许读取回复数据包。我发现如果回复中的源端口相同,Windows防火墙将允许它重新传入。

3 个答案:

答案 0 :(得分:3)

异常告诉您:您无法创建具有相同源端口的两个活动套接字。我不知道ASIO,但是你应该能够在关闭线程之前创建套接字,保持对套接字和线程的引用以供以后使用,并且一旦数据发送线程空闲,就加入回来并发送任何线程。其他的东西。

编辑:只需要一点点努力,你也可以创建一个套接字,你不必等到一个线程的整个数据都被发送出来了:让拥有套接字的工作线程监听队列数据块(理想情况下就是您要发送的有效负载的大小),并从多个线程向此队列发送任意数据块的负载。

答案 1 :(得分:1)

将回复发送到同一个套接字(您收到客户端的请求),而不是创建新的套接字 但请确保您不要同时从两个线程发送到同一套接字

答案 2 :(得分:1)

您应该能够使用SO_REUSEADDR套接字选项将多个套接字绑定到同一个地址。但话虽如此,你不想这样做,因为它没有指定哪个套接字将在该端口上接收传入数据(你必须检查所有套接字的传入数据)

更好的选择就是使用相同的套接字来发送回复 - 这可以安全地从多个线程完成而无需任何额外的同步(因为您正在使用UDP)。