我的目标是从Windows计算机发现本地网络中Linux计算机"服务器"的IP地址.从另一台Linux计算机"客户端"我可以做到:
ping -c1 server.local
Run Code Online (Sandbox Code Playgroud)
并得到答复."服务器"和"客户端"都运行Avahi,因此这很容易.但是,我想从我的Python应用程序中发现"服务器"的IP地址,该应用程序在MS Windows和Linux计算机上运行.注意:在不运行mDNS软件的MS Windows计算机上,没有主机名解析(显然ping在所述Windows系统上不起作用).
我知道pyzeroconf的存在,这是我试图使用的模块; 但是,文档很少,对我来说不是很有帮助.使用类似的工具avahi-discover,我认为计算机发布_workstation._tcp.local.的mDNS类型的服务类型(显然是虚拟端口9,丢弃服务)的PTR记录可能等同于DNS A记录.或者我可能完全误解了mDNS机制.
如何通过Python中的mDNS发现计算机的IP地址(或获取计算机的IP地址列表)?
显然socket.gethostbyname可以在运行并配置为使用mDNS软件的计算机上运行(如Avahi):
Python 2.6.5 (r265:79063, Apr 16 2010, 13:09:56)
[GCC 4.4.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import socket
>>> socket.gethostbyname('server.local')
'192.168.42.42'
Run Code Online (Sandbox Code Playgroud)
但是,在没有运行mDNS软件的Windows计算机上(默认),我得到:
Python 2.7.1 (r271:86832, Nov 27 2010, 18:30:46) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import socket …Run Code Online (Sandbox Code Playgroud) 我使用Fedora 18和avahi命令行工具(版本0.6.31)
我使用avahi-resolve-host-name来发现我子网上单元的IP地址,以便在开发过程中进行测试.我使用Wireshark监控请求和响应.在一次成功的请求和响应之后,Wireshark上没有进一步的请求,但该工具仍然返回一个IP地址.计算机/ avahi守护进程/其他东西是否有可能"缓存"结果?
问题:我希望通过每次调用avahi-resolve-host-name发送请求数据包.这可能吗?
原因:可以说我得到'误报'.我尝试解决'test1.local',我得到了一个结果IP,但该单元不再位于此IP.我希望每次都发送请求,这样我就可以避免看到IP地址不正确的单位.
用户A正在Android或iOS设备上运行您的应用.用户A可以自动查找并与附近的其他(<20米?)用户B和C(跨平台)进行通信,无论他们是在运行Android还是iOS,并且没有任何用户具有互联网连接(离线).
我相信这是一个常用的功能,对这个问题有一个明确的答案对移动开发社区来说是一个很大的好处.
如何实现所需的功能?
它甚至可能吗?
答:是的.像Firechat和Spaceteam这样的应用程序可以做到这一点,因此它必须是可能的.
Multipeer:仅限iOS,无法实现跨平台.
Alljoyn:iOS绑定只是Objective-C,没有实现Single Codebase.
Mono.Zeroconf:据说需要单独的平台实现,所以不要实现单一代码库?
Open Garden SDK:将是一个很好的解决方案,除了它实际上还不存在.
我几天来一直在研究这个话题,但我还没有找到明确的答案.部分原因可能是人们使用了很多不同的术语,如网状网络,ad-hoc网络,zeroconf,DNS-SD等,这使得搜索变得困难.
如果你对我在stackoverflow和其他地方所做的一些研究感兴趣,这里有一些注释和链接(我在这篇文章中直接放入的链接数量有限).
我经常访问已设置为使用.local顶级域名下的域的Windows域.这与Bonjour/Zeroconf有冲突,后者保留.local供自己使用.许多平台支持Bonjour开箱即用(包括Mac OS,iPhone和Ubuntu),并且在出现这种混淆时会出现许多名称解析问题.
我有一个适当的手动(每个工作站)的解决方法为Mac OS通过建立一个/etc/resolver/ntdomain.local按resolver(5)效果很好.不幸的是,这需要在每个工作站上进行手动更改,并且无法在iPhone上运行.
我正在寻找的是一种将*.ntdomain.local通过mDNS进入的请求重定向到特定的单播DNS服务器的方法.如果需要,我不介意编写一些代码.我可以在Debian或Windows 2003上部署.看起来Avahi可能是我正在寻找的库.
这可以在不注册子域中的每个地址的情况下完成,或者是否可以ntdomain.local将该点的单个NS记录注册到Windows DNS服务器?
链路本地多播名称解析(LLMNR)是一种基于多播DNS的服务发现的Microsoft技术.它与Bonjour/Zeroconf兼容吗?如果是这样,API在哪里?我认为服务发现以某种方式融入了vanilla DNS解析(gethostbyname()?),但是服务广告呢?
我的程序是我的第一个真正的Erlang程序,我已经有了一个良好的开端.我让它听取消息,阅读它们并解析它们.我也发送它们.困扰我的一件小事是我不能在5353号港口发送,我已经尝试了一切.我的机器上的所有其他应用程序都可以通过端口5353,SubEthaEdit,iTunes,iChat进行监听和发送.
解决方案必须在端口5353上广播发送,这就是原因.
"如果收到的多播DNS查询中的源UDP端口不是端口5353,则表示发起查询的客户端是一个不能完全实现所有多播DNS的简单客户端.在这种情况下,多播DNS响应者必须发送一个UDP响应通过单播直接返回到客户端查询数据包的源IP地址和端口.这种单播响应必须是传统的单播DNS服务器生成的传统单播响应;例如,它必须重复查询ID以及查询包中给出的问题."
它们都在发送多播消息时报告端口:5353.我真的希望我的应用程序玩得很好并做同样的事情,发送端口5353.这是我现在的模块.
-module(zeroconf).
-include("zeroconf.hrl").
-export([open/0,start/0]).
-export([stop/1,receiver/0]).
-export([send/1]).
-define(ADDR, {224,0,0,251}).
-define(PORT, 5353).
send(Domain) ->
{ok,S} = gen_udp:open(0,[{broadcast,true}]), % I really want this Port to be 5353 :-(
% this doesn't complain or throw errors but it also doesn't work :-(
%{ok,S} = gen_udp:open(?PORT,[{reuseaddr,true}, {ip,?ADDR}, {broadcast,true},multicast_ttl,4}, {multicast_loop,false}, binary]),
P = #dns_rec{header=#dns_header{},qdlist=[#dns_query{domain=Domain,type=ptr,class=in}]},
gen_udp:send(S,?ADDR,?PORT,inet_dns:encode(P)),
gen_udp:close(S).
Run Code Online (Sandbox Code Playgroud)
这是一些输出的样子.
这是来自SubEthaEdit的QUERY,在本地网络上查找其他实例,请注意它显示Port:5353
From: {192,168,0,105}
Port: 5353
Data: {ok,{dns_rec,{dns_header,0,true,'query',true,false,false,false,false,0},
[],
[{dns_rr,"_see._tcp.local",ptr,in,0,0,
"jhr@Blackintosh._see._tcp.local",undefined,[],
false}],
[],[]}}
Run Code Online (Sandbox Code Playgroud)
现在这是我的模块中查询本地网络上的iTunes实例,注意它说Port:59795代码就像现在一样,该端口是随机的.我真的希望它是5353.
From: {192,168,0,105}
Port: 59795
Data: {ok,{dns_rec,{dns_header,0,false,'query',false,false,false,false,false,
0},
[{dns_query,"_daap._tcp.local",ptr,in}],
[],[],[]}}
Run Code Online (Sandbox Code Playgroud)
有没有人对UDP多播有任何神秘的见解?更新所以我可以尝试接受答案.我想我不能这样做.
我正在构建一个使用Zeroconf的.net-microframework应用程序.现有的zeroconf解决方案似乎都依赖于dns-sd.dll或.netmf不支持的.net的其他一些互操作功能.
有没有你知道的纯粹的C#版zeroconf(或dns-sd)?
我正在开发一个带有嵌入式网络服务器的控制设备.Web服务器为任何请求它的Web浏览器提供控制接口(从Windows浏览器,Mac浏览器,iPhone android等).
我遇到的问题是通常知道如何访问设备的一般方法.即在Web浏览器中键入的地址.
固定IP对我的用户来说太技术了,可能会出错,因为我的设备可以插入许多不同的本地网络.使用uPnp服务发现需要在某些平台上在客户端上运行软件,并不像仅键入Web地址那样自然.我想实现名称解析.
我当前的实现使用netbios协议.所以从Windows浏览器我可以键入// controller /它可以工作,但这不适用于Mac或智能手机.我还可以尝试实现苹果mDnsresponder,它应该让Mac和iPhone玩得开心(虽然我认为我只限于//controller.local/).也许类似的东西也存在于Android,Symbian等,但是没有一个更通用的解决方案来创建一个我可以尝试的网络名称?
该平台目前基于TI Cortex M3处理器和lwIP.
任何有关如何找到解决方案的帮助或建议都非常感谢.
亲切的问候,
短发
我正在尝试在http://www.mono-project.com/Mono.Zeroconf上测试ZeroConf示例.
我正在运行OpenSuse 11和Mono 2.2.
我的服务器代码是:
using System;
using Mono.Zeroconf;
namespace zeroconftestserver
{
class MainClass
{
public static void Main(string[] args)
{
RegisterService service = new RegisterService ();
service.Name = "test server";
service.RegType = "_daap._tcp";
service.ReplyDomain = "local.";
service.Port = 6060;
// TxtRecords are optional
TxtRecord txt_record = new TxtRecord ();
txt_record.Add ("Password", "false");
service.TxtRecord = txt_record;
service.Register();
Console.WriteLine("Service registered!");
Console.ReadLine();
}
}
}
Run Code Online (Sandbox Code Playgroud)
但我无法使用示例客户端浏览器代码或mzclient找到我的注册服务.
谢谢!
我正在构建一个原生的Bonjour/Zeroconf库,需要构建DNS查询记录以广播到其他机器.我曾尝试通过Erlang源代码查找,但由于我对Erlang相对较新,因此它在所有inet_XXX.erl和.hrl文件的内容中变得非常密集.我有一个侦听器,用于接收和解析DNS记录有效负载,我只是无法弄清楚如何创建查询记录.我真正需要知道的是我需要传递给inet_dns:encode()来获取我可以发送的二进制文件.这是我想要做的.
{ok,P} = inet_dns:encode(#dns_query{domain="_daap._tcp.local",type=ptr,class=in})
Run Code Online (Sandbox Code Playgroud)
这是我得到的错误
10> test:send().
** exception error: {badrecord,dns_rec}
in function inet_dns:encode/1
in call from test:send/0
11>
Run Code Online (Sandbox Code Playgroud)