读写 UDP 连接套接字?
我们正在尝试让两个程序以类似游戏的方式相互通信。它们与中央服务器保持 TCP 连接以获取“控制”类型信息,中央服务器确保两个客户端都能收到这些信息。然后,两个客户端使用 sendto() 和 recvfrom() 与 udp 服务器进行通信,后者仅将收到的信息发送到连接的另一个客户端。
现在的问题是,如果您有家庭路由器或私人办公网络,则到其他客户端的 udp 服务器 sendto() 将被防火墙过滤掉,除非您打开了端口,这比我们想要的要多得多我们的客户要做的。
但我不想失去 UDP 的好处——我不关心数据包丢失和顺序。我愿意自己处理这一切。
那么,我可以可靠地创建一个读写连接的UDP套接字吗?我记得过去尝试过这个,只是遇到了很多问题,我放弃了,转而使用 sendto() - receivevfrom() 解决方案,然后才意识到我刚刚把自己搞砸了我们的专用网络之外。
对于如何处理这个问题有什么建议吗?对于连接的 UDP 套接字有什么最佳实践或我应该特别注意的事情?真的可行吗?
(我用纯 C 语言编写了这一切)。
We are trying to get two programs to communicate with each other in a game-like fashion. They maintain a TCP connection with a central server for "control" type information, which that central server ensures both clients receive. The two clients then communicate with a udp server using sendto() and recvfrom() which just sends the information it receives to the other client connected.
Now, the problem is that, if you have a home router or private office network, the udp server sendto() to the other client will be filtered out by the firewall, unless you have a port opened, which is way more than we want our customers to do.
But I don't want to lose the benefits of UDP — I don't care about packet loss and order. I am willing to manage all that myself.
So, can I reliably create a read-write connected UDP socket? I recall trying this in the past, and just having so many problems that I gave up and went to the sendto() - recvfrom() solution, before realising that I'd just screwed myself outside of our private network.
Any suggestions for how to deal with this? Any best practices or things I should pay particular attention to for connected UDP sockets? Is it really even feasible?
(I'm coding this all in pure C).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我相信这就是 UPnP 的设计目的。 TCP 穿透 NAT 的原因是,第 3 层设备可以相当容易地将入站数据包与先前通过出站连接建立的活动 TCP 会话关联起来。 IIRC、UPnP 通过 UDP 层解决了相同的问题,但它确实需要路由器的支持,因此它可能无法与旧的或配置不良的网络设备一起使用。
我不知道应用程序程序员有什么有趣的细节,但希望这能为您指明正确的方向。
I believe this is what UPnP was designed for. The reason that TCPs punch through NATs is that it is fairly easy for a layer-3 device to associate inbound packets with an active TCP session previously established through an outbound connection. IIRC, UPnP solves the same problem with a layer over UDP, but it does require support from the router, so it may not work with old or poorly-configured network devices.
I don't know any interesting details for application programmers, but hopefully this points you in the right direction.
Minupnpd http://miniupnp.free.fr/ 附带了一个库,您可以使用它来执行 UPnP和 NAT-PmP,这将使您摆脱许多国内路由器的困扰。您还可以像 Xbox 和 PS-3 一样,使用 Teredo 和/或 IPv6(如果盒子上启用了它们);当 UPnP 和 NAT-PmP 都无法帮助您时,这些有时会起作用。
还有另一种方法,称为 ICE,并使用称为 STUN 和 TURN 的协议组合。此处的库: http://www.pjsip.org/pjnath/docs/html/
如果站点的边界路由器无法与这七种解决方案(UPnP、NAT-PmP、Teredo、IPv6、ICE、STUN 和 TURN)之一配合使用,则它要么完全损坏,要么被故意锁定。
Minupnpd http://miniupnp.free.fr/ comes with a library you can use that will do both UPnP and NAT-PmP, which will get you out from a lot of domestic routers. You can also do as the XBox and PS-3 do, which is use Teredo and/or IPv6 if they are enabled on the box; those will sometimes work when neither UPnP nor NAT-PmP will get you anywhere.
And then there's the other approach, which is called ICE, and uses a combination of protocols called STUN and TURN. Libraries here: http://www.pjsip.org/pjnath/docs/html/
If a site's border router won't work with one of those seven solutions (UPnP, NAT-PmP, Teredo, IPv6, ICE, STUN and TURN), it's either totally broken or deliberately locked down.