轻量级局域网对等发现的解决方案?


9

我建立了一个用于纯跨平台编程的库。我用它制作的游戏在Android,Pc,Linux,Mac等系统中运行良好。

ENET库提供了网络功能,因此我的应用程序之间的所有通信都不兼容TCP或UDP,而只能使用自定义协议,即使最终基于UDP也是如此。

我认为用ENET无法实现我想要的功能,这就是为什么我在这里寻求帮助!

可以说,我的Android手机,笔记本电脑和PC中都运行着相同的游戏。它们都在同一个wifi网络中,因此都在LAN中,无论是其Wifi热点(?)还是家用路由器。

我需要这3个对等方中的每一个来发现网络中的其他2个。这仅意味着在LAN网络中找到运行中的应用程序的IP,以便能够在它们之间托管多人游戏。

我只能想到一种有效的方法,即UDP广播,等待响应,但是如果这是解决方案,则我需要一些小东西,因为这是实现的唯一目的。

其他方法可能是尝试连接到LAN地址子范围中的所有IP,但是我不认为OS会和我一起在此:p


2
我认为应该采取一些UDP广播的方式,但我不理解您的反对意见,还是ENET不支持广播?
罗伊T.12年

没错,它没有,它只能播放已知道同行..
格里姆肖

Answers:


5

就像很多人说的那样,解决方案是使用UDP广播,但是涉及很多实现细节。最近,我遇到了同样的问题,在制定了解决方案之后,我写了一篇博客文章,并以LAN聊天服务器/客户端的形式创建了一个示例项目。我将在这里进行总结,但是您应该查看它们以获取更多详细信息和真实代码。

根据ENet的创建者Lee Salzman 的描述,它的工作方式如下:

  • 您的游戏服务器作为ENet主机在一个套接字上运行
  • 服务器还绑定到已知的“监听”端口,作为常规UDP套接字(即不是ENet主机)
  • 客户端向该监听端口发送UDP广播消息(即IP 255.255.255.255),并等待响应
  • 局域网中的所有服务器都将收到该“扫描”消息,并做出响应。理想情况下,您可以使用运行游戏服务器(ENet主机)的端口进行响应。这样,您就不必在固定端口上运行游戏服务器)
  • 客户端收到一些响应后,它将知道存在哪些服务器。然后,您可以选择其中一个作为常规ENet对等方进行连接。此时,客户端不再需要UDP“扫描程序”套接字。

好消息是ENet提供了使用套接字的包装函数,因此您可以在ENet中完成所有操作。坏消息是包装纸非常薄。您需要了解套接字编程,例如做什么select()。这就是为什么我鼓励您看一下博客文章示例项目,以便您可以复制/粘贴代码并节省大量时间的原因。

如果您选择执行自己的实现,则有一些注意事项和陷阱:

  • 侦听器/扫描器必须是UDP,因此您需要使用来创建enet_socket_create(ENET_SOCKET_TYPE_DATAGRAM)(或SOCK_DGRAM用于普通的旧套接字编程)
  • 对于服务器“监听器”,允许使用enet_socket_set_option(socket, ENET_SOCKOPT_REUSEADDR, 1)(或SO_REUSEADDR)重用端口地址,以便多个服务器可以在同一IP上运行
  • 对于客户端“扫描器”,必须使用enet_socket_set_option(scanner, ENET_SOCKOPT_BROADCAST, 1)(或SO_BROADCAST)在UDP套接字上启用广播,否则无法发送到广播地址。这是一项安全功能,使意外淹没网络变得更加困难。

不幸的是,这并不是一个“轻量级”的解决方案。样本项目总共有数百个LOC。如果将其打包到ENet的实用程序库中会很好,但是我发现对于游戏服务器,您通常希望在服务器回复中发送一些与游戏有关的更多信息,以使其变得有用,例如:

  • 游戏类型(例如“合作”,“死亡竞赛”)
  • 服务器正在运行的“地图”,“级别”或“广告系列”
  • 服务器的播放器数和最大播放器数
  • 任何其他与游戏有关的信息都会影响客户端是否连接的决定。考虑一下游戏中的“服务器浏览器”及其显示的信息种类。

这正是我的想法。广播是必经之路。
卢卢斯

3

当您不想离开图书馆时,可以使用暴力破解并尝试连接到每个可能的地址。大多数家庭局域网是C类网络(/ 24),其中IP地址的前24位相同,而后8位不同。因此,您只有255个可能的IP地址。

但是,进行UDP广播将是更清洁的选择。只需将UDP数据包发送到255.255.255.255,同一路由器后面的所有客户端都会收到它。然后,他们可以将答复发送到数据包的源IP和源端口,以通知发送方它们存在。


2
请请请请 不要暴力破解。
Trevor Powell,

@TrevorPowell ...因为...?
菲利普

2
因为这是错误的解决方案。它在大学(不使用C类网络)或企业(通常也不使用C类网络)中都将不起作用,并且两家公司的IT员工都将非常不喜欢由每个参与者承担的负担暴力破解尝试在每次单击“刷新”按钮时将消息发送到其网络中的每个IP地址。这只是解决这个问题不好的办法。在没有数学制作服务器的情况下定位潜在同伴的问题正是广播的目的。使用广播。各个方面都更好。:)
Trevor Powell

1

您可以看看DNS-SD / ZeroConf / Avahi / Bonjour / mDNS。这是Apple用于共享打印机,iTunes文件夹等的东西,但已在其他地方采用。Avahi是Linux使用的开源版本(不确定是否仅是Linux),不确定整个组件的可移植性(尽管大多数平台都有实现)。

综上所述,仅进行UDP广播可能会更容易。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.