转自:http://gkaindl.com/software/arduino-ethernet/bonjour

Bonjour/Zeroconf with Arduino

DownloadVersion
History

Bonjour/Zeroconf with Arduino

A small implementation of Bonjour/Zeroconf (Wikipedia)
that can run on your ethernet-equipped Arduino board! It implements both MDNS (multicast DNS) and DNS-SD (DNS Service Discovery), so that you can register services from your Arduino, but also discover services registered by other nodes on the network.

As examples, you can use this library to register a small web-server running on your Arduino, which can then be easily discovered by other users on your network. Or use it to discover nodes offering a service your Arduino sketch can work with. It's just like
Bonjour running on your desktop.

Documentation

The library ships with 4 extensively commented examples, but here's an additional run-down of the public methods. Nevertheless, I suggest to have a look at the examples for a short introduction to the library.

int begin();
int begin(const char* bonjourName);

In order to initialize the library, you must call begin() before any other library method, but after your Ethernet shield itself has been initialized, preferably within your setup() function. When you initialize the library, you can supply
an (arbitrary) name under which your Arduino board can then be referenced on the network.

The default name is "arduino", which means that you can access the board conveniently on the Bonjour network via the MDNS name "arduino.local" — However, do not attach the ".local" postfix when you specify the name in begin().

The method will return a non-zero result if the library could be initialized successfully, otherwise 0 will be returned.

void run();

You should call run() at least once per loop() iteration. This gives the Bonjour module a chance to fulfill your requests and to interact with the Bonjour network.

If you fail to call run() periodically, the Bonjour library will not work at all.

int setBonjourName(const char* bonjourName);

You can use this method to change the Bonjour name of your Arduino board at any time after setting the initial name via begin(). Changing the Bonjour name after you have already registered services might cause some clients to fail to connect properly for a
short time, until the name change has propagated.

Do not include the ".local" postfix when you specify a new Bonjour name!

This method returns a non-zero value on success and 0 if there was an internal (memory) error.

int addServiceRecord(const char* name,
uint16_t port,
MDNSServiceProtocol_t proto);
int addServiceRecord(const char* name,
uint16_t port,
MDNSServiceProtocol_t proto,
const char* textContent);

The addServiceRecord() methods enable you to register a service running on your Arduino board with the Bonjour network, so that it can be discovered by other Bonjour peers. The difference between them only is that the second version takes an
additional text content argument, whereas the first one does not.

The first argument is the name of your service. Typically, this is an instance name and a service name, separated by a dot. The service name needs to be additionally prefixed with an underscore. An incredibly extensive list of defined service names is available here.

Examples of a valid name-argument would be "My Arduino Web Server._http" or "My Arduino iChat client._presence".

The second argument specifies the port on which the service is listening on your Arduino board. As an example, webservers are typically listening on port 80. You need to make sure that you actually are listening for network traffic on the port!

The third argument is the TCP/UDP-layer protocol your service is running on. Specify MDNSServiceTCP for TCP-based services or MDNSServiceUDP for UDP-based services.

The "textContent" argument lets you specify a TXT record to be associated with your service. TXT records are typically used to contain additional information about a service, such as the initial path on the server in case of a HTTP endpoint. A good list of
defined TXT keys for many services can be found here,
and the DNS-SD TXT record format in general is described here.
Specify the TXT record as a zero-terminated string.

The method will return a non-zero value upon success and zero otherwise (for example, when memory is exhausted).

void removeServiceRecord(uint16_t port,
MDNSServiceProtocol_t proto);
void removeServiceRecord(const char* name,
uint16_t port,
MDNSServiceProtocol_t proto);

Call removeServiceRecord() to remove unregister a service from the Bonjour network. The arguments should match those given to a previous addServiceRecord() call. The service identified by the arguments will be removed, and an announcement of
the removal will be distrubted to Bonjour peers immediately.

The method returns a non-zero value on success and 0 on failure.

void removeAllServiceRecords();

You can use removeAllServiceRecords(); to remove all previously added service registrations at once, so that your Arduino board does not vend services anymore.

void setNameResolvedCallback(BonjourNameFoundCallback newCallback);

Use setNameResolvedCallback() to specify a callback function of your own, which will be called when you resolve a host name over Bonjour.

The argument must be a pointer to a function which takes two arguments (in this order): A "const char*" and a "const byte[4]": The former will hold the host name that you wanted resolved, the latter will hold the IP address of the host (4 bytes) if it could
be resolved, or NULL if no Bonjour peer responded to the query.

Be sure to have a callback set before you attempt to resolve a host name with resolveName()!

int resolveName(const char* name,
unsigned long timeout);

Provided that you have already specified a callback, you can use resolveName() to find the IP address of a Bonjour host. The first argument is the host's Bonjour name (again, without the ".local" postfix), the second argument is a timeout (in
milliseconds) that you want the query to run for before it times out, calling the callback with a NULL IP address argument.

While a query is running, the Bonjour library will resend the query every second, until your timeout is reached or a response has been obtained.

If you want to run a query indefinitely (for example, to wait for a host with a given Bonjour name to join the network), you can specify zero (0) as the timeout argument to disable the timeout mechanism.

resolveName() will return a non-zero value on success or 0 on failure. Only one name query can run at any given time: Calling resolveName() again before the current query is finished will cause the current query to be overwritten by the new one.

void cancelResolveName();

If you want to stop a currently running name query, call cancelResolveName() to cancel it immediately. Your callback function will not be called in this case.

int isResolvingName()

Use isResolvingName() to find out whether the library is currently busy resolving a host name. If so, this method will return a non-zero value, otherwise it will return zero.

void setServiceFoundCallback(BonjourServiceFoundCallback newCallback);

setServiceFoundCallback() is used to specify a callback that is called when a service is discovered. You need to specify a callback of your own before you can discover services.

The argument is a pointer to a function that takes the following arguments (in this order): A "const char*", an "MDNSServiceProtocol", another "const char*", a "const byte[4]", an "unsigned short" and one more "const char*": They will be filled with the service
type (such as "_http"), the transport protocol (MDNSServiceTCP or MDNSServiceUDP), the service name (such as "My Arduino Web Server"), the service endpoint's IP address (4 bytes), the endpoint's port number and (if available) the service record's TXT contents
(zero-terminated), NULL otherwise.

When your service discovery timeout is reached, your callback will be called one more time, but all arguments (except the service type and protocol) will be NULL.

If you do not specify a callback, you cannot discover any services.

int startDiscoveringService(const char* serviceName,
MDNSServiceProtocol_t proto,
unsigned long timeout);

startDiscoveringService() causes the Bonjour library to query the network for services of a particular type, provided that you have specified an appropriate callback.

The first argument denotes the service type, prefixed by an underscore (such as "_http"). For a comprehensive list of service types, have a look here.
The second argument is the desired transport protocol (either MDNSServiceTCP or MDNSServiceUDP, for TCP or UDP, respectively).

The third argument is the timeout (or total duration) of the search in milliseconds. The Bonjour library will keep waiting for replies until this timeout is reached, when it will call the callback again, but with a NULL argument as service name and IP address,
so that you know that the discovery time has elapsed.

Note that the Bonjour library will resend the discovery request every 10 seconds: Thus, if you specify more than 10 seconds (10000 milliseconds) as timeout argument, you will receive duplicate results as well, so be prepared.

You can specify a timeout value of zero (0) to let the discovery process run indefinitely.

You can only discover a single service type concurrently, so subsequent calls of this method while another discovery is running will overwrite the old discovery request.

void stopDiscoveringService();

Call the stopDiscoveringService() method to immediately stop discovering services. In this case, your callback will not be called.

int isDiscoveringService();

Use the isDiscoveringService() method to find out if a service discovery is currently running: If so, a non-zero value will be returned. Otherwise, zero is returned.

Notes a.k.a. "Things you should know"

  • Registering services is very reliable, but discovering services is not (due to the complexity of the process): If it is necessary for your application, you might want to run the discovery process more than once. Generally,
    it works rather well, though!
  • Due to memory limitations, you can only discover a maximum of 6 service endpoints per host and service type. For example, if a host vends 10 HTTP endpoints, only the first 6 will be found. If you want to risk memory exhaustion/corruption,
    you can change the MDNS_MAX_SERVICES_PER_PACKET macro in EthernetBonjour.cpp.
  • Also due to similar memory limitations, you can only vend up to 8 services running on your board. If you want to change this limitation, edit "NumMDNSServiceRecords" in EthernetBonjour.h (but note that the WIZnet chipset
    on the ethernet shield only supports 4 sockets anyway, one already taken up by the Bonjour library, so 8 services might be way too much anyway. Thus, you could also lower this constant to free up some memory).
  • The library is rather large (about 14K) and will thus only fit onto Arduino boards with at least 32K of flash memory (such as the Duemilanove, the Nano 3.0 or the MEGA). You might be able to fit it onto older boards by getting
    rid of the discovery stuff if you're only interested in registering services, for example. Personally, I've developed the library on a Duemilanove and use it on MEGA boards.
  • The library has only been tested with Apple's Bonjour (on both a small and rather large network): Service registration will most likely work with other implementations as well, service discovery might not — Give
    it a try and email me patches!
  • The implementation adheres to the Zeroconf specs, but is rather "noisy" in that service registration is resent with a Time-To-Live of 2 minutes — This is because I do not want stale registrations to hang around for long when
    you reset your board, and a modern network should really be able to handle the additional couple of bytes every two minutes ;-)

Pro Tip: Save code size if you don't need all features

Bonjour/ZeroConf is a complex protocol, so the full library is quite large and can eat up a lot of flash space on your Arduino. However, if all you want is giving your Arduino board a Bonjour name like arduino.local, so that you don't need to remember
any IP addresses (or get them dynamically via DHCP), you can disable some advanced features at compile time for massive size savings (up to 7K).

If you open the file EthernetBonjour.cpp within the library, you'll notice two macros defined right at the top: HAS_SERVICE_REGISTRATION andHAS_NAME_BROWSING. They are set to enabled per default. The first
one governs some code necessary only if you want to register link-local Bonjour service endpoints. You can turn this off if you don't need it (saves about 1.5K). The latter controls name and service browsing: If you don't want to send any queries to link-local
Bonjour, turn this off to save about 5.5K of code size. Service registration depends on name browsing, so you can either turn off just the former, or both, but not just the latter. If you turn off the features, but use them anyway, the resulting code will
simply time out at all times.

Again, the main focus for these (and the only thing I have tested) is to turn everything off except host name advertising, so that you can, as an example, have a sensor platform run at the Bonjour address MySensorPlatform.local for convenience, but
don't need any other Bonjour features.

Bonjour/Zeroconf with Arduino的更多相关文章

  1. 【读书笔记】iOS网络-使用Bonjour实现自组织网络

    Bonjour就是这样一种技术:设备可以通过它轻松探测并连接到相同网络中的其他设备,整个过程只需要很少的用户参与或是根本就不需要用户参与.该框架提供了众多适合于移动的使用场景,如基于网络的游戏,设备间 ...

  2. 【读书笔记】iOS-网络-使用Bonjour实现自组织网络

    Bonjour就是这样一种技术:设备可以通过它轻松探测并连接到相同网络中的其他设备,整个过程只需要很少的用户参与或是根本就不需要用户参与.该框架提供了众多适合于移动的使用场景,如基于网络的游戏,设备间 ...

  3. 一百元的智能家居——Asp.Net Mvc Api+讯飞语音+Android+Arduino

    大半夜的,先说些废话提提神 如今智能家居已经不再停留在概念阶段,高大上的科技公司都已经推出了自己的部分或全套的智能家居解决方案,不过就目前的现状而言,大多还停留在展厅阶段,还没有广泛的推广起来,有人说 ...

  4. nodejs操作arduino入门(javascript操作底层硬件)

    用Javascript来操作硬件早就不是一件稀奇的事情了. 所以作为一名电子专业出身的FE,我也打算尝试一下用js来驱动arduino: 要想操作这些底层硬件,肯定是需要一些工具的,我这里介绍的工具主 ...

  5. 了解 ARDUINO 101* 平台

    原文链接 简介 作为一名物联网 (IoT) 开发人员,您需要根据项目的不同需求,选择最适合的平台来构建应用. 了解不同平台的功能至关重要. 本文第一部分比较了 Arduino 101 平台和 Ardu ...

  6. 在web浏览器上显示室内温度(nodeJs+arduino+socket.io)

    上次的nodejs操作arduino入门篇中实现了如何连接arduino.这次我们来实现通过arduino测量室内温度并在浏览器上显示出来. [所需材料] 硬件:LM35温度传感器,arduino u ...

  7. 初探物联网 - 基于Arduino的气象站和View and Data API的结合实例

    如果你参加了上个月在北京的Autodesk 开发者日,你应该看到了我做的关于Arduino的物联网实例演示,如果你没看到,欢迎参加14号在上海的开发者日,到时候我会再演(xian)示(bai)一下. ...

  8. Arduino 1602液晶屏实验和程序

    在Arduino IDE中, 项目->加载库->管理库中搜索LiquidCrystal,然后安装即可 1.接线图 2.引脚图 3.最简单程序 #include <LiquidCrys ...

  9. Arduino uno 教程~持续更新~

    http://arduino.osall.com/index.html http://study.163.com/search.htm?t=2&p=Arduino http://www.ard ...

随机推荐

  1. VNC ( Virtual Network Computing )

    VNC is used to display an X windows session running on another computer. Unlike a remote X connectio ...

  2. java 数组中求最值

    java中数组求最值,这在实际的开发中差点儿用不到,可是在面试中会偶尔被问到,这是考你主要的思维能力,如今说下这个题的基本思路 思路: 1:先定义一个变量,通常是用数组的第一个值 2:在循环中推断(从 ...

  3. TI C66x DSP 系统events及其应用 - 5.6(INTMUX)

    系统event 0~127(包含了eventCombiner的输出event 0~3)与CPU支持的12个可屏蔽中断是通过INTMUX寄存器进行映射的(不包含NMI.RESET).能够选择将系统eve ...

  4. 18124 N皇后问题

    18124 N皇后问题 时间限制:2000MS  内存限制:65535K提交次数:0 通过次数:0 题型: 编程题   语言: G++;GCC;VC Description 有N*N的国际象棋棋盘,要 ...

  5. 基于Dynamic Proxy技术的方法AOP拦截器开发

    在面向对象编程中,会用到大量的类,并且会多次调用类中的方法.有时可能需要对这些方法的调用进行一些控制.如在权限管理中,一些用户没有执行某些方法的权限.又如在日志系统中,在某个方法执行完后,将其执行的结 ...

  6. Linux命令(七)——网络配置和网络通信

    在使用网络前,需要对linux主机进行基本的网络配置,配置后可以使该主机能够同其他主机进行正常的通信. 一.网络配置 1.ifcfg-ethn网络配置文件 所有的网络接口配置文件均存放在/etc/sy ...

  7. sizeof运算符、malloc函数及free函数

    一.sizeof运算符的用法 1.sizeof运算符给出某个类型或变量在内存中所占据的字节数. int a;  sizeof(a)=4;  //sizeof(int)=4; double b;  si ...

  8. angular4 select 绑定(ngModel)对象

    欢迎加入前端交流群交流知识&&获取视频资料:749539640 <h1>My Application</h1> <select [(ngModel)]=& ...

  9. 使用ssh和putty操控远程的linux server

    windows下没有openssh,今天这里使用openssh-server作为server,windows下使用putty作为client, putty主要流程分以下几步: step 1: 下载pu ...

  10. AJAX复习笔记

    AJAX 是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术.通过在后台与服务器进行少量数据交换,AJAX 可况下更新以使网页实现异步更新. 工作原理: AJAX是基于现有的Internet ...