极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 32477|回复: 8

【翻译教程】enc28J60 和 Arduino (6)——自动更新动态域名

[复制链接]
发表于 2012-10-15 10:43:35 | 显示全部楼层 |阅读模式
本帖最后由 zcbzjx 于 2013-2-22 19:55 编辑

继续。。这篇文章主要讲用arduino更新动态域名服务器的功能。建议大家先百度下,了解一下动态域名
原文请看这儿,翻译不对的地方大家指正。



    在这篇教程我将告诉你如何编写代码更新在著名的动态域名服务提供商之一no-ip服务器上的DNS记录。

动态IP地址

    如果您在家里或者移动连接到互联网,你可能会有一个动态的公网IP地址,每次连接它可能会改变。
    如果你要和网络上的一个设备联系,你需要知道这个设备的公网IP地址,如果这个地址是动态的,你可能不知道这个IP地址是多少(这样你就无法联系上这个设备)。

动态DNS

    在互联网上你可以找到免费的动态DNS(DDNS)服务:他允许你将你选择的域名和一个IP地址绑定,并且可以随时更新IP地址(绑定不同的IP地址)。
   
    更新可以有不同的方法:
  • 在你的PC上用一个客户端更新;
  • 在你的路由器上应用DDNS功能;
  • 让Arduino为我们做这个事情。


NO-IP

    应用比较多的动态域名服务商之一是NO-IP
    如果你注册了NO-IP的免费服务,你最多可以设置5台主机,使用Hosts/重定向功能。
   
    在这个教程,我注册了以下域名:enctutorial.no-ip.info

动态域名客户端

    每个动态域名客户端,执行以下步骤:
  • 得到实际的公网IP。
  • 公网IP和动态域名服务器注册的IP地址进行比较。
  • 如果不同,通过服务提供商的API更新DNS记录。


代码

    完整的代码共享在GitHub,接下来我将解释它们如何工作。

工作流程

    代码的工作流程如下图所示:

    作为一个4个状态的有限状态机(FSM)(也可百度有限状态机):
  • 程序启动的时候,它在空闲(IDLE)状态,在给定的时间(CHECK_IP_INTERVAL常数)后,它检查实际的公网IP;
  • 为获取公网IP发送请求,程序处于等待响应(WAITING_FOR_PUBLIC_IP)状态,如果在给定的时间(REQUEST_TIMEOUT常数)没有收到响应,重发请求,相应的重复尝试次数(attempts)+1,当这个计数器次数大于最大尝试次数(MAX_ATTEMPTS),程序回到空闲(IDLE)状态。
  • 程序如果收到响应,获得实际的IP地址,它就和动态域名解析的IP地址进行比较。如果不同,就切换到NOIP_NEEDS_UPDATE状态,否则它返回到空闲(IDLE)状态。
  • 如果需要更新,程序发送更新请求到NO-IP服务器并切换到WAITING_FOR_NO_IP状态。如果再给定时间没有收到响应,和WAITING_FOR_PUBLIC_IP状态一样,会再次尝试,达到尝试最大次数,返回空闲(IDLE)状态。如果收到响应,它会返回更新结果,并回到空闲(IDLE)状态。


公网IP

    要获得实际的公网IP,我在我的网站写了一个简单的PHP页面:

Arduino浏览这个页面获得实际的公网IP。

DNS记录和比较

程序用dnsLookup()方法获取域名绑定的IP地址。然后将结果转换成一个字符串,与用上面方法获得的实际公网IP地址用compareTo()方法进行比较。
  1. if(!ether.dnsLookup(noIP_host)) {
  2. [...]
  3. } else {
  4.   for(int i = 0; i < 4; i++) {
  5.     dnsIp = dnsIp + String(ether.hisip[i]);
  6.     if(i < 3) dnsIp = dnsIp + ".";
  7.   }
  8.   if(actualIp.compareTo(dnsIp) == 0) {
  9.     Serial.println("No update needed :)");
  10.     [...]
  11.   } else {
  12.     Serial.println("Update needed :(");
  13.     actual_status = STATUS_NOIP_NEEDS_UPDATE;
复制代码
认证

    NO-IP在更新DNS记录前要进行身份认证。在代码中定义了一个常量:

    这个值是用户名:密码字符串,必须用base64编码,我们使用在线的编码器


测试

    为了测试程序的作用,我们手动更新,让这个域名绑定一个错误的IP地址:

    然后我们运行程序:

    Arduino获得了实际的公网IP,解析了域名绑定的IP,这两个不同,对域名绑定IP成功进行了更新,一段时间后,又进行另外一轮检查,这两个地址没有差异,就没有更新的必要。
    重新查看NO-IP网站上的记录,确认进行了更新:

    如果认证的密匙错误,程序检测并显示错误:


返回目录

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复

使用道具 举报

发表于 2012-10-15 23:10:18 | 显示全部楼层
沙发哈,非常好的系列教程哦...实用...让Arduino在网络中扩展...
回复 支持 反对

使用道具 举报

发表于 2012-10-16 09:57:05 | 显示全部楼层
谢谢老师分享了~!
回复 支持 反对

使用道具 举报

发表于 2012-10-17 22:47:22 | 显示全部楼层
翻译后最好贴下完整代码了,省的还要到网站去找例子,后面有2个webled的例子不错,使用它+继电器就能控制灯了
回复 支持 反对

使用道具 举报

发表于 2012-10-18 12:29:17 | 显示全部楼层
辛苦啦!看来要多学英语才行
回复 支持 反对

使用道具 举报

发表于 2012-10-22 07:44:36 | 显示全部楼层
lz英文还也
回复 支持 反对

使用道具 举报

发表于 2013-5-14 14:23:39 | 显示全部楼层
谢谢楼主分享,正在一篇一篇看
回复 支持 反对

使用道具 举报

发表于 2013-8-25 22:59:20 | 显示全部楼层
感谢楼主分享,学习中~~~
回复 支持 反对

使用道具 举报

发表于 2015-7-28 11:44:07 | 显示全部楼层
老师为什么用的用的就不工作了呢,可以解答一下嘛
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则 需要先绑定手机号

Archiver|联系我们|极客工坊

GMT+8, 2024-4-23 16:06 , Processed in 0.048646 second(s), 26 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表