我使用Bonjour API注册了一条记录。现在我想知道我刚刚发布的记录的内容。我通过指定一个NULL主机名创建它,意思是“使用守护进程的默认值”,但我找不到一种简单的方法来查询它是什么!
使用avahi,很容易:我调用avahi_client_get_host_name()
来获取机器主机名的起始值。
对于avahi和Bonjour,SRV记录的值可以在注册的生命周期内更改 - 如果注册是使用NULL主机名完成的,则记录的主机名会在必要时自动更新。我想要的是在执行注册时获取主机名的初始值的方法。
请注意,在我的Snow Leopard测试计算机上,默认的多播主机名不与gethostname(2)
中的计算机名称相同。
我能想到的四种解决方案:
strings(3)
搜索,并在我的地址空间中找到了四个多播主机名实例,但这可能是巧合,因为该名称用于其他事情。即使我所追求的字符串在我的进程中某处,我找不到一个可以很好地检索它的API。在uDNS.c中重新实现逻辑。它从以下组合中获取机器的主机名:
gethostname(2)
或同等的重新实施这种逻辑似乎是不可行的。
目前,我正倾向于进行查找以获取初始SRV注册的值,但这似乎并不理想。什么是正确的解决方案?
答案 0 :(得分:2)
我需要做到这一点。您想使用ConvertDomainNameToCString宏(包含在mDNSEmbeddedAPI.h中),您需要访问核心mDNS结构。
以下是如何获得已注册的确切Bonjour / Zeroconf主机名:
char szHostname[512];
extern mDNS m;
ConvertDomainNameToCString(&m.MulticastHostname, szHostname);
我希望这会对你有所帮助。
答案 1 :(得分:0)
为了记录,我选择(4),抓住机器的配置,将守护进程正在使用的主机名汇总在一起,而不必查询它。
static char* getBonjourDefaultHost()
{
char* rv = 0;
#ifdef __APPLE__
CFStringRef name = SCDynamicStoreCopyLocalHostName(NULL);
if (name) {
int len = CFStringGetLength(name);
rv = new char[len*4+1];
CFStringGetCString(name, rv, len*4+1, kCFStringEncodingUTF8);
CFRelease(name);
}
// This fallback is completely incorrect, but why should we care...
// Mac does something crazy like <sysctl hw.model>-<MAC address>.
if (!rv)
rv = GetHostname(); // using gethostname(2)
#elif defined(WIN32)
CHAR tmp[256+1];
ULONG namelength = sizeof(tmp);
DynamicFn<BOOL (WINAPI*)(COMPUTER_NAME_FORMAT,LPSTR,LPDWORD)>
GetComputerNameExA_("Kernel32", "GetComputerNameExA");
if (!GetComputerNameExA_.isValid() ||
!(*GetComputerNameExA_)(ComputerNamePhysicalDnsHostname, tmp, &namelength))
tmp[0] = 0;
// Roughly correct; there's some obscure string cleaning mDNSResponder does
// to tidy up funny international strings.
rv = tmp[0] ? strdup(tmp) : strdup("My Computer");
#elif defined(__sun)
// This is exactly correct! What a relief.
rv = GetHostName();
#else
#error Must add platform mDNS daemon scheme
#endif
return rv;
}
答案 2 :(得分:0)
从命令行可以使用scutil
命令获取本地(Bonjour)主机名:
scutil --get LocalHostName
以编程方式通过kSCPropNetLocalHostName
框架使用SystemConfiguration
密钥获取此内容。
答案 3 :(得分:0)
我知道已经回答了这个问题,但是我根据Pierz在回答的后半部分所说的内容,来看看如何使用SystemConfiguration框架来实现它。
这是我正在工作的内容,认为这可以节省其他人在一段时间内使用Google搜索: 在Swift中:
import SystemConfiguration
let store = SCDynamicStoreCreate(nil, "ipmenu" as CFString, nil, nil )
if let hostNames = SCDynamicStoreCopyValue(store, "Setup:/Network/HostNames" as CFString){
if let hostName:String = (hostNames[kSCPropNetLocalHostName]) as? String {
print("Host name:\(hostName)")
}
}