← 返回列表
🔗 原文
UDP广播与轻松发现网络服务
UDP Broadcasting and Easily Finding Network Services

Local area networks (LANs) that use technologies like Ethernet and Wi-Fi are incredibly useful for letting devices talk with each other. Yet a core problem here is knowing which devices are where on the network, as anyone who has ever tried to add a network printer or network share to their system can probably attest to. Unless you happen to know the IP address of the LAN device, the port, and protocol, the target device may as well be located on the Moon without further help, such as automatic network discovery in lieu of waddling over to the device and reading the label listing its IP address.

Over the decades quite a few ways have been developed to enable such network discovery, with many of them using UDP broadcast as the first step. By broadcasting a global message on the entire LAN, any device that has an actively listening UDP socket on that particular port can parse said message and decide whether it’s feeling sociable enough to reply.

The topic of UDP broadcasting is however not as straightforward as it may sound if you’re just getting started, including the existence of many opinions on the ‘right way’. There is also a massive divide between a sprawling service discovery protocol like mDNS and a light-weight one like that one that I had to implement a few years ago for an open source project.

Network Broadcasting

The obvious advantage of a broadcast message is that a client device that seeks its protocol soul mate on the LAN doesn’t need to ping all possible IP address and subnets. Instead,  a broadcast message is designed so that all connected networking devices know that it should be forwarded to all other known devices. Thus with a single message from the client, in theory, only a single message will then neatly land at every single other connected system.

Of course, this ignores happy joy fun things such as convoluted network configurations, such as those involving overlapping Wi-Fi repeaters and subsequent routing, but in general we can assume that this is how it works. Various edge cases and fascinating complications of these will be considered in a later section.

Much of this service auto-discovery is tossed under the header of ‘zero-configuration networking‘, or zeroconf for people who don’t like typing. The best part about zeroconf is probably that there are so many standards here, ranging from DNS-SD to mDNS, UPnP, SLP and others. Perhaps unsurprisingly, one of the major issues here is that platform support here is spotty, with mDNS – despite being one of the most universal – not having much support outside of MacOS/OS X with Bonjour and Linux/BSD with Avahi.

Thus while trying to add the auto-discovery of NymphCast receivers and media servers by NymphCast clients, I found myself asking the daunting question of whether I was at risk of being about to embark on reinventing the proverbial wheel. After all, nobody wants to become the subject of an xkcd comic.

UDP Discovery Basics

As it turns out, I ought not to have been too worried, as despite looking everywhere I could find nothing along the lines of the NyanSD network service discovery (NSD) protocol that I ended up implementing and integrating into NymphCast. What I wanted after all was the most no-frills NSD possible that could be easily integrated, while working the same across just about any desktop, server and embedded platform imaginable.

All that’s needed for this is a way to create an appropriate UDP socket, and a way to either broadcast a query and receive the response, or to listen for incoming UDP packets. Here you can figure out the platform-native method for each target platform, or not reinvent the wheel and use an existing networking library for C++ like Poco. This is what I used for NyanSD, along with my ByteBauble utility to handle endianness conversions.

For the UDP server — the listening side — the procedure is fairly standard, with a regular UDP listening socket. As UDP is a connectionless protocol, there is not a lot of preamble here, just a UDP socket instance (here Poco::Net::DatagramSocket), which is bound to the target port and regularly polls for any fresh UDP packets to process. This can all be seen in the single source file for NyanSD which covers both the client and server side code.

Where things get spicy is with the client that sends the broadcast query and waits for any replies. If we were to just shove the query data into the socket along with the request to toss it over to a regular IP address, not a lot would happen. To make it into a broadcast request we need a few things:

  1. Let the network subsystem know that we want to do broadcast things.
  2. Create the special broadcast address for the target network interface.

With Poco the first point is easily handled by simply calling setBroadcast(true) on the UDP socket instance. For BSD sockets this sets the appropriate flag on the socket, which is essentially repeated across all OS implementations due to how prevalent the BSD socket library is.

The second point can be summarized for IPv4 as a curt ‘make it end with .255’. For example 192.168.0.255 when the client network interface’s IP address is 192.168.0.42. If there are multiple interfaces on the client system, you can go through the list one by one to broadcast on each of them before filtering out potential duplicate returns.

As for how to do broadcasting with IPv6: you don’t, as this protocol relies on multicast and special multicast receiver groups, which is another kettle of fish and of not much relevance for LANs.

Complications

If you look at the NyanSD API, it may give the impression that the query process is incredibly straightforward, with the sendQuery() function neatly returning a stack of remote systems that responded to our query. While these are definitely all the responses, it’s important to remember that NyanSD queries every single network interface. This means that the responses are likely to contain duplicates, which may even come from the loopback address when a service runs locally.

The filtering of this is captured in the NymphCast client library (libnymphcast) where the findServers() function in the main source file calls the isDuplicate() and isDuplicateName() functions, as well as the removeLoopback() function that nukes any responses that match a remote service found via a non-loopback interface. This last filtering is essential for NymphCast when e.g. using playback groups that would otherwise get confused by a stray loopback address.

Although one may think that such in-depth filtering is unnecessary if all you have is a single Wi-Fi or Ethernet interface in your system, one of the curveballs that I encountered during real-life testing was apparently related to Wi-Fi repeaters. For some reason it seems that the way that the repeaters did their broadcasting led to erroneous duplication of packets and thus multiple returns from a single system.

Depending on your exact use case and network configuration you may encounter any such issues and perhaps an exciting new one.

NyanSD Findings

Over the years that NyanSD has been used in the NymphCast project, it has proven to be one of the most reliable and probably nearly zero-fuss components. I have so far used it on Windows, various Linux distributions, FreeBSD, Haiku, Android, and the ESP32 via FreeRTOS and ESP-IDF. What this experience has proven to me most of all is that service discovery doesn’t have to be complicated.

The basic UDP protocol is simple and reliable enough that, barring a very sick LAN, there shouldn’t be any issues here. Assuming you get your filtering sorted of the responses, it’s probably the last part of a project to worry about.

One thing that I’m also very happy with in NyanSD is that there’s no set port in the protocol, like how mDNS always uses port 5353. What this means is that I can have NyanSD listen with a UDP socket on the same port as the NymphCast server’s TCP socket, which also means that different services with their own port can be targeted directly rather than every NyanSD-enabled service on the network getting blasted by every NyanSD query.

I did also do some work on a NyanSD daemon as a more central services database, but so far I have had no real need for it in a practical deployment. I guess that such a thing could be very useful if the port of a service is not set in stone, but generally that’s the one aspect of network services that tends to be boringly predictable.

🤖 AI 总结
UDP广播可解决局域网中设备发现难题,通过广播报文让设备自动找到可用网络服务。

Local area networks (LANs) that use technologies like Ethernet and Wi-Fi are incredibly useful for letting devices talk with each other. Yet a core problem here is knowing which devices are where on the network, as anyone who has ever tried to add a network printer or network share to their system can probably attest to. Unless you happen to know the IP address of the LAN device, the port, and protocol, the target device may as well be located on the Moon without further help, such as automatic network discovery in lieu of waddling over to the device and reading the label listing its IP address.

Over the decades quite a few ways have been developed to enable such network discovery, with many of them using UDP broadcast as the first step. By broadcasting a global message on the entire LAN, any device that has an actively listening UDP socket on that particular port can parse said message and decide whether it’s feeling sociable enough to reply.

The topic of UDP broadcasting is however not as straightforward as it may sound if you’re just getting started, including the existence of many opinions on the ‘right way’. There is also a massive divide between a sprawling service discovery protocol like mDNS and a light-weight one like that one that I had to implement a few years ago for an open source project.

Network Broadcasting

The obvious advantage of a broadcast message is that a client device that seeks its protocol soul mate on the LAN doesn’t need to ping all possible IP address and subnets. Instead,  a broadcast message is designed so that all connected networking devices know that it should be forwarded to all other known devices. Thus with a single message from the client, in theory, only a single message will then neatly land at every single other connected system.

Of course, this ignores happy joy fun things such as convoluted network configurations, such as those involving overlapping Wi-Fi repeaters and subsequent routing, but in general we can assume that this is how it works. Various edge cases and fascinating complications of these will be considered in a later section.

Much of this service auto-discovery is tossed under the header of ‘zero-configuration networking‘, or zeroconf for people who don’t like typing. The best part about zeroconf is probably that there are so many standards here, ranging from DNS-SD to mDNS, UPnP, SLP and others. Perhaps unsurprisingly, one of the major issues here is that platform support here is spotty, with mDNS – despite being one of the most universal – not having much support outside of MacOS/OS X with Bonjour and Linux/BSD with Avahi.

Thus while trying to add the auto-discovery of NymphCast receivers and media servers by NymphCast clients, I found myself asking the daunting question of whether I was at risk of being about to embark on reinventing the proverbial wheel. After all, nobody wants to become the subject of an xkcd comic.

UDP Discovery Basics

As it turns out, I ought not to have been too worried, as despite looking everywhere I could find nothing along the lines of the NyanSD network service discovery (NSD) protocol that I ended up implementing and integrating into NymphCast. What I wanted after all was the most no-frills NSD possible that could be easily integrated, while working the same across just about any desktop, server and embedded platform imaginable.

All that’s needed for this is a way to create an appropriate UDP socket, and a way to either broadcast a query and receive the response, or to listen for incoming UDP packets. Here you can figure out the platform-native method for each target platform, or not reinvent the wheel and use an existing networking library for C++ like Poco. This is what I used for NyanSD, along with my ByteBauble utility to handle endianness conversions.

For the UDP server — the listening side — the procedure is fairly standard, with a regular UDP listening socket. As UDP is a connectionless protocol, there is not a lot of preamble here, just a UDP socket instance (here Poco::Net::DatagramSocket), which is bound to the target port and regularly polls for any fresh UDP packets to process. This can all be seen in the single source file for NyanSD which covers both the client and server side code.

Where things get spicy is with the client that sends the broadcast query and waits for any replies. If we were to just shove the query data into the socket along with the request to toss it over to a regular IP address, not a lot would happen. To make it into a broadcast request we need a few things:

  1. Let the network subsystem know that we want to do broadcast things.
  2. Create the special broadcast address for the target network interface.

With Poco the first point is easily handled by simply calling setBroadcast(true) on the UDP socket instance. For BSD sockets this sets the appropriate flag on the socket, which is essentially repeated across all OS implementations due to how prevalent the BSD socket library is.

The second point can be summarized for IPv4 as a curt ‘make it end with .255’. For example 192.168.0.255 when the client network interface’s IP address is 192.168.0.42. If there are multiple interfaces on the client system, you can go through the list one by one to broadcast on each of them before filtering out potential duplicate returns.

As for how to do broadcasting with IPv6: you don’t, as this protocol relies on multicast and special multicast receiver groups, which is another kettle of fish and of not much relevance for LANs.

Complications

If you look at the NyanSD API, it may give the impression that the query process is incredibly straightforward, with the sendQuery() function neatly returning a stack of remote systems that responded to our query. While these are definitely all the responses, it’s important to remember that NyanSD queries every single network interface. This means that the responses are likely to contain duplicates, which may even come from the loopback address when a service runs locally.

The filtering of this is captured in the NymphCast client library (libnymphcast) where the findServers() function in the main source file calls the isDuplicate() and isDuplicateName() functions, as well as the removeLoopback() function that nukes any responses that match a remote service found via a non-loopback interface. This last filtering is essential for NymphCast when e.g. using playback groups that would otherwise get confused by a stray loopback address.

Although one may think that such in-depth filtering is unnecessary if all you have is a single Wi-Fi or Ethernet interface in your system, one of the curveballs that I encountered during real-life testing was apparently related to Wi-Fi repeaters. For some reason it seems that the way that the repeaters did their broadcasting led to erroneous duplication of packets and thus multiple returns from a single system.

Depending on your exact use case and network configuration you may encounter any such issues and perhaps an exciting new one.

NyanSD Findings

Over the years that NyanSD has been used in the NymphCast project, it has proven to be one of the most reliable and probably nearly zero-fuss components. I have so far used it on Windows, various Linux distributions, FreeBSD, Haiku, Android, and the ESP32 via FreeRTOS and ESP-IDF. What this experience has proven to me most of all is that service discovery doesn’t have to be complicated.

The basic UDP protocol is simple and reliable enough that, barring a very sick LAN, there shouldn’t be any issues here. Assuming you get your filtering sorted of the responses, it’s probably the last part of a project to worry about.

One thing that I’m also very happy with in NyanSD is that there’s no set port in the protocol, like how mDNS always uses port 5353. What this means is that I can have NyanSD listen with a UDP socket on the same port as the NymphCast server’s TCP socket, which also means that different services with their own port can be targeted directly rather than every NyanSD-enabled service on the network getting blasted by every NyanSD query.

I did also do some work on a NyanSD daemon as a more central services database, but so far I have had no real need for it in a practical deployment. I guess that such a thing could be very useful if the port of a service is not set in stone, but generally that’s the one aspect of network services that tends to be boringly predictable.

原文
UDP Broadcasting and Easily Finding Network Services

Local area networks (LANs) that use technologies like Ethernet and Wi-Fi are incredibly useful for letting devices talk with each other. Yet a core problem here is knowing which devices are where on the network, as anyone who has ever tried to add a network printer or network share to their system can probably attest to. Unless you happen to know the IP address of the LAN device, the port, and protocol, the target device may as well be located on the Moon without further help, such as automatic network discovery in lieu of waddling over to the device and reading the label listing its IP address.

Over the decades quite a few ways have been developed to enable such network discovery, with many of them using UDP broadcast as the first step. By broadcasting a global message on the entire LAN, any device that has an actively listening UDP socket on that particular port can parse said message and decide whether it’s feeling sociable enough to reply.

The topic of UDP broadcasting is however not as straightforward as it may sound if you’re just getting started, including the existence of many opinions on the ‘right way’. There is also a massive divide between a sprawling service discovery protocol like mDNS and a light-weight one like that one that I had to implement a few years ago for an open source project.

Network Broadcasting

The obvious advantage of a broadcast message is that a client device that seeks its protocol soul mate on the LAN doesn’t need to ping all possible IP address and subnets. Instead,  a broadcast message is designed so that all connected networking devices know that it should be forwarded to all other known devices. Thus with a single message from the client, in theory, only a single message will then neatly land at every single other connected system.

Of course, this ignores happy joy fun things such as convoluted network configurations, such as those involving overlapping Wi-Fi repeaters and subsequent routing, but in general we can assume that this is how it works. Various edge cases and fascinating complications of these will be considered in a later section.

Much of this service auto-discovery is tossed under the header of ‘zero-configuration networking‘, or zeroconf for people who don’t like typing. The best part about zeroconf is probably that there are so many standards here, ranging from DNS-SD to mDNS, UPnP, SLP and others. Perhaps unsurprisingly, one of the major issues here is that platform support here is spotty, with mDNS – despite being one of the most universal – not having much support outside of MacOS/OS X with Bonjour and Linux/BSD with Avahi.

Thus while trying to add the auto-discovery of NymphCast receivers and media servers by NymphCast clients, I found myself asking the daunting question of whether I was at risk of being about to embark on reinventing the proverbial wheel. After all, nobody wants to become the subject of an xkcd comic.

UDP Discovery Basics

As it turns out, I ought not to have been too worried, as despite looking everywhere I could find nothing along the lines of the NyanSD network service discovery (NSD) protocol that I ended up implementing and integrating into NymphCast. What I wanted after all was the most no-frills NSD possible that could be easily integrated, while working the same across just about any desktop, server and embedded platform imaginable.

All that’s needed for this is a way to create an appropriate UDP socket, and a way to either broadcast a query and receive the response, or to listen for incoming UDP packets. Here you can figure out the platform-native method for each target platform, or not reinvent the wheel and use an existing networking library for C++ like Poco. This is what I used for NyanSD, along with my ByteBauble utility to handle endianness conversions.

For the UDP server — the listening side — the procedure is fairly standard, with a regular UDP listening socket. As UDP is a connectionless protocol, there is not a lot of preamble here, just a UDP socket instance (here Poco::Net::DatagramSocket), which is bound to the target port and regularly polls for any fresh UDP packets to process. This can all be seen in the single source file for NyanSD which covers both the client and server side code.

Where things get spicy is with the client that sends the broadcast query and waits for any replies. If we were to just shove the query data into the socket along with the request to toss it over to a regular IP address, not a lot would happen. To make it into a broadcast request we need a few things:

  1. Let the network subsystem know that we want to do broadcast things.
  2. Create the special broadcast address for the target network interface.

With Poco the first point is easily handled by simply calling setBroadcast(true) on the UDP socket instance. For BSD sockets this sets the appropriate flag on the socket, which is essentially repeated across all OS implementations due to how prevalent the BSD socket library is.

The second point can be summarized for IPv4 as a curt ‘make it end with .255’. For example 192.168.0.255 when the client network interface’s IP address is 192.168.0.42. If there are multiple interfaces on the client system, you can go through the list one by one to broadcast on each of them before filtering out potential duplicate returns.

As for how to do broadcasting with IPv6: you don’t, as this protocol relies on multicast and special multicast receiver groups, which is another kettle of fish and of not much relevance for LANs.

Complications

If you look at the NyanSD API, it may give the impression that the query process is incredibly straightforward, with the sendQuery() function neatly returning a stack of remote systems that responded to our query. While these are definitely all the responses, it’s important to remember that NyanSD queries every single network interface. This means that the responses are likely to contain duplicates, which may even come from the loopback address when a service runs locally.

The filtering of this is captured in the NymphCast client library (libnymphcast) where the findServers() function in the main source file calls the isDuplicate() and isDuplicateName() functions, as well as the removeLoopback() function that nukes any responses that match a remote service found via a non-loopback interface. This last filtering is essential for NymphCast when e.g. using playback groups that would otherwise get confused by a stray loopback address.

Although one may think that such in-depth filtering is unnecessary if all you have is a single Wi-Fi or Ethernet interface in your system, one of the curveballs that I encountered during real-life testing was apparently related to Wi-Fi repeaters. For some reason it seems that the way that the repeaters did their broadcasting led to erroneous duplication of packets and thus multiple returns from a single system.

Depending on your exact use case and network configuration you may encounter any such issues and perhaps an exciting new one.

NyanSD Findings

Over the years that NyanSD has been used in the NymphCast project, it has proven to be one of the most reliable and probably nearly zero-fuss components. I have so far used it on Windows, various Linux distributions, FreeBSD, Haiku, Android, and the ESP32 via FreeRTOS and ESP-IDF. What this experience has proven to me most of all is that service discovery doesn’t have to be complicated.

The basic UDP protocol is simple and reliable enough that, barring a very sick LAN, there shouldn’t be any issues here. Assuming you get your filtering sorted of the responses, it’s probably the last part of a project to worry about.

One thing that I’m also very happy with in NyanSD is that there’s no set port in the protocol, like how mDNS always uses port 5353. What this means is that I can have NyanSD listen with a UDP socket on the same port as the NymphCast server’s TCP socket, which also means that different services with their own port can be targeted directly rather than every NyanSD-enabled service on the network getting blasted by every NyanSD query.

I did also do some work on a NyanSD daemon as a more central services database, but so far I have had no real need for it in a practical deployment. I guess that such a thing could be very useful if the port of a service is not set in stone, but generally that’s the one aspect of network services that tends to be boringly predictable.

中文翻译
UDP广播与轻松发现网络服务

使用以太网和Wi-Fi等技术的局域网(LAN)非常有用,可以让设备互相通信。然而,这里的一个核心问题是知道哪些设备在网络上的位置,任何曾经尝试向系统添加网络打印机或网络共享的人可能都能证实这一点。除非你碰巧知道局域网设备的IP地址、端口和协议,否则目标设备可能就像位于月球上一样难以触及,除非有进一步的帮助,例如自动网络发现,而不是走到设备前读取其IP地址标签。

几十年来,人们开发了不少方法来实现这种网络发现,其中许多方法将UDP广播作为第一步。通过在整个局域网上广播一条全局消息,任何在该特定端口上拥有主动监听UDP套接字的设备都可以解析该消息,并决定是否足够友善地回复。

然而,UDP广播的话题并不像听起来那么简单,尤其是对于刚刚入门的人来说,关于“正确方式”存在许多观点。此外,像mDNS这样庞大的服务发现协议与几年前我为了一个开源项目不得不实现的那种轻量级协议之间存在着巨大的鸿沟。

网络广播

广播消息的明显优势在于,寻求局域网内协议灵魂伴侣的客户端设备不需要ping所有可能的IP地址和子网。相反,广播消息的设计使得所有连接的网络设备都知道它应该被转发到所有其他已知设备。因此,从客户端发送一条消息,理论上只有一条消息会整齐地到达每一个其他连接的系统。

当然,这忽略了一些令人愉快的复杂网络配置,例如涉及重叠的Wi-Fi中继器及后续路由的情况,但通常我们可以假设这就是它的工作方式。各种边缘情况和有趣的并发症将在后面的部分中讨论。

这种服务自动发现大多归入“零配置网络”(zeroconf)的范畴,对于不喜欢打字的人来说。零配置最好的部分可能是这里有太多的标准,从DNS-SD到mDNS、UPnP、SLP等等。或许不足为奇的是,这里的主要问题之一是平台支持参差不齐,mDNS虽然是最通用的标准之一,但在MacOS/OS X(Bonjour)和Linux/BSD(Avahi)之外几乎没有太多支持。

因此,在尝试为NymphCast客户端添加NymphCast接收器和媒体服务器的自动发现功能时,我发现自己面临一个令人生畏的问题:我是否正冒着重新发明众所周知的轮子的风险?毕竟,没有人想成为xkcd漫画的主题。

UDP发现基础

结果证明,我不必过于担心,因为尽管我到处寻找,却找不到任何类似于我最终实现并集成到NymphCast中的NyanSD网络服务发现(NSD)协议。毕竟,我想要的是最简单的NSD,可以轻松集成,并且在几乎所有可想象到的桌面、服务器和嵌入式平台上都能以相同方式工作。

为此所需要的只是一种创建适当UDP套接字的方法,以及一种广播查询并接收响应或监听传入UDP数据包的方法。你可以为每个目标平台找出平台原生方法,或者不重复造轮子,使用现有的网络库,比如C++的Poco。这就是我在NyanSD中使用的,以及我的ByteBauble工具来处理字节序转换

对于UDP服务器——监听端——过程相当标准,使用常规的UDP监听套接字。由于UDP是一种无连接协议,这里没有太多前奏,只有一个UDP套接字实例(这里用Poco::Net::DatagramSocket),它绑定到目标端口,并定期轮询是否有新的UDP数据包需要处理。所有这些都可以在NyanSD的单个源文件中看到,该文件涵盖了客户端和服务器端代码。

有趣的部分在于发送广播查询并等待任何回复的客户端。如果我们只是将查询数据连同请求一起塞入套接字,并将其发送到常规IP地址,那么不会发生太多事情。要使其成为广播请求,我们需要一些东西:

  1. 让网络子系统知道我们要进行广播操作
  2. 为目标网络接口创建特殊的广播地址。

使用Poco,第一点很容易处理,只需在UDP套接字实例上调用setBroadcast(true)即可。对于BSD套接字,这会设置套接字上的适当标志,由于BSD套接字库非常普及,这实际上在所有操作系统实现中都是重复的。

第二点对于IPv4可以概括为简洁的“使其以.255结尾”。例如,当客户端网络接口的IP地址是192.168.0.42时,广播地址为192.168.0.255。如果客户端系统上有多个接口,你可以逐个遍历列表,在每个接口上广播,然后过滤掉潜在的重复返回。

至于如何使用IPv6进行广播:你不能,因为该协议依赖于多播和特殊的多播接收组,这是另一回事,而且与局域网关系不大。

复杂性

如果你查看NyanSD API,可能会觉得查询过程非常简单直接,sendQuery()函数整洁地返回一堆响应了我们查询的远程系统。虽然这些肯定都是响应,但重要的是要记住,NyanSD会查询每一个网络接口。这意味着响应很可能包含重复项,甚至可能来自当服务在本地运行时出现的环回地址。

这种过滤在NymphCast客户端库(libnymphcast)中得到了体现,其中主源文件中的findServers()函数调用了isDuplicate()isDuplicateName()函数,以及removeLoopback()函数,该函数会删除任何与非环回接口匹配的远程服务响应。这种最后的过滤对于NymphCast至关重要,例如在使用播放组时,否则可能会因为错误的环回地址而混乱。

尽管有人可能认为,如果系统中只有单个Wi-Fi或以太网接口,这种深入的过滤是不必要的,但我在实际测试中遇到的一个意外情况显然与Wi-Fi中继器有关。出于某种原因,中继器进行广播的方式似乎导致了数据包的错误重复,从而从单个系统返回了多个响应。

根据你的具体使用场景和网络配置,你可能会遇到任何此类问题,或者一些令人兴奋的新问题。

NyanSD发现结果

在NymphCast项目中,NyanSD被使用的这些年里,它已被证明是最可靠、几乎零麻烦的组件之一。到目前为止,我已在Windows、各种Linux发行版、FreeBSD、Haiku、Android以及通过FreeRTOS和ESP-IDF运行的ESP32上使用过它。这段经历最让我确信的是,服务发现不必复杂。

基本的UDP协议足够简单可靠,除非局域网非常糟糕,否则不应该出现任何问题。假设你正确处理了响应的过滤,它很可能是项目中最后需要担心的部分。

我对NyanSD还非常满意的一点是,协议中没有像mDNS那样固定的端口(比如mDNS总是使用端口5353)。这意味着我可以让NyanSD使用与NymphCast服务器TCP套接字相同的端口监听UDP套接字,这也意味着可以针对不同服务使用自己的端口直接进行定向查询,而不是每次NyanSD查询都轰炸网络上所有启用NyanSD的服务。

我还做了一些关于NyanSD守护进程的工作,作为一个更集中的服务数据库,但到目前为止,在实际部署中我并没有真正需要它。我猜如果服务的端口不是固定的,这种东西可能会非常有用,但通常来说,端口是网络服务中往往非常可预测的一个方面。