5

我正在寻找一种方法,让 LAN 中的客户端无需任何配置即可找到我的服务器应用程序的所有实例。我不想自己破解某些东西,而是想使用现有的解决方案。就个人而言,我需要用 Python 来完成它,但我很高兴听到任何其他语言的解决方案。

那么为什么我不使用avahiOpenSLP或其他Zeroconf / SLP解决方案呢?好吧,还有一些额外的标准,我的印象是上述系统都不符合它们。

我正在寻找一个解决方案:

  • 灵活。它必须不需要超级用户权限,即只使用端口>1024。
  • 固体。它必须允许在一台机器上提供相同和不同服务类型的多个服务,并且即使在启动广告服务器的实例停止或崩溃时也能继续广告服务。
  • 便携。它几乎必须在任何地方运行,或者至少在 *BSD、Debian/gentoo/RedHat/SuSe Linux、Mac OS X、Solaris 和 Windows NT 上运行。
  • 。理想情况下,一个 Python 脚本将是整个解决方案。我对地址自动配置或类似的东西一点也不感兴趣,尽管我不情愿地接受一个有很多我不需要的功能的解决方案。此外,任何一次性设置都是严格禁止的。

我期待这样的事情:

def registerService(service): # (type, port)
    if listen(multicast, someport):
        if fork() == child:
            services = [service]
            for q in queriesToMe():
                if q == DISCOVERY:
                    answer(filter(q.criteria, services))
                elif q == ADVERTISE and q.sender == "localhost":
                    services.append(q.service)
    else:
        advertiseAt("localhost", service)
4

3 回答 3

3

我编写了一个匹配所有这些标准的应用程序/库(目前是 Python 和 CLI 接口)。它被称为减号。事实证明,甚至不需要分叉。

于 2009-03-17T18:09:38.947 回答
2

对于 LAN 中的节点发现,我使用了 Twisted 和 UDP 多播。希望对你也有帮助。

链接到解释如何操作的扭曲文档: https ://twistedmatrix.com/documents/current/core/howto/udp.html#auto3

这是基于扭曲代码的服务器/客户端的基本实现。如果您运行一次,它会自行回答,但所有检查代码和额外功能都已删除,以使其更易于阅读。

from twisted.internet.protocol import DatagramProtocol
from twisted.internet import reactor

class MulticastPingPong(DatagramProtocol):
    MULTICAST_ADDR = ('228.0.0.5', 8005)
    CMD_PING = "PING"
    CMD_PONG = "PONG"

    def startProtocol(self):
        """
        Called after protocol has started listening.
        """
        # Set the TTL>1 so multicast will cross router hops:
        self.transport.setTTL(5)
        # Join a specific multicast group:
        self.transport.joinGroup(self.MULTICAST_ADDR[0])

        self.send_alive()

    def send_alive(self):
        """
        Sends a multicast signal asking for clients.
        The receivers will reply if they want to be found.
        """
        self.transport.write(self.CMD_PING, self.MULTICAST_ADDR)

    def datagramReceived(self, datagram, address):
        print "Datagram %s received from %s" % (repr(datagram), repr(address))

        if datagram.startswith(self.CMD_PING):
            # someone publishes itself, we reply that we are here
            self.transport.write(self.CMD_PONG, address)
        elif datagram.startswith(self.CMD_PONG):
            # someone reply to our publish message
            print "Got client: ", address[0], address[1]


if __name__ == '__main__':
    reactor.listenMulticast(8005, MulticastPingPong(), listenMultiple=True)
    reactor.run()
于 2013-08-13T16:02:32.343 回答
1

我假设您可以控制客户端应用程序,而不仅仅是服务器应用程序,在这种情况下,Pyro可能适合您。

灵活:使用非特权端口。

坚固:多年来一直保持良好状态。

便携:纯 Python 并在多个平台上经过良好测试。

Light:我认为 Pyro 对于你所得到的东西来说很轻。也许要求一个 Python 脚本对于网络命名服务来说是不现实的?

即使您不想实际使用 Pyro 的“远程对象”范例,您仍然可以只使用它的命名服务。

于 2009-02-20T06:43:55.700 回答