使用Objective C套接字发送MDNS请求



我的iPad无法在网络上"看到"其他设备。所以我想发送一个UDP MDNS数据包,这样网络就会给IP提供网络上最新的设备,这样我就可以在iPad上执行镜像。我能够创建一个套接字,但我发送的数据不正确。什么好主意吗?

struct icmphdr
    {
        u_int16_t qr;       /* type sub-code */
        u_int16_t opcode;
        u_int16_t aa;
        u_int16_t tc;
        u_int16_t rd;
        u_int16_t ra;
        u_int16_t z;
        u_int16_t ad;
        u_int16_t cd;
        u_int16_t rcode;
        u_int16_t q_count;
}
// Create the socket connection
    int sd = socket(AF_INET, SOCK_DGRAM, 0);
// Configure the port and ip we want to send to
    struct sockaddr_in broadcastAddr; // Make an endpoint
    memset(&broadcastAddr, 0, sizeof (broadcastAddr));
    broadcastAddr.sin_family = AF_INET;
    broadcastAddr.sin_len = sizeof(broadcastAddr);
    broadcastAddr.sin_addr.s_addr = htonl(INADDR_ANY);
    broadcastAddr.sin_addr.s_addr = inet_addr("224.0.0.251");
    broadcastAddr.sin_port = htons(5353); // Set port 5353
    bind (sd, (struct sockaddr *)&broadcastAddr, sizeof(broadcastAddr));
    struct icmphdr req;
    req.qr=00;      // Reponse: Message is query
    req.opcode=00;  // Opcode: Standard Query (0)
    req.tc=00;      // Truncated: Message is not truncated
    req.rd=00;      // Recursion desired: Don't do query recursively
    req.z=00;       // Z: reserved (0)
    req.ad=00;      // Non-authenticated data: Unacceptable
    req.ra=02;      // Questions: 2
    req.cd = 00;
    req.rcode = 00;
    req.q_count = 00;
    req.aa = 00;
    if (sendto(sd, &req, sizeof(req), 00, (struct sockaddr*)&broadcastAddr, sizeof broadcastAddr)) {
        NSLog(@"%s",strerror(errno));
    }
    close(sd);

首先-你怎么知道你的iPad没有看到Bonjour设备?除非是在非常早期的iOS版本上,否则它应该能够。

second - Bonjour查询(通常)对PTR记录的DNS请求完成,而不是ICMP。我敢说,没有办法获得网络上每个 Bonjour设备的列表。因此,您既可以请求感兴趣的服务,也可以查询_services._dns-sd._udp。本地获取服务列表,然后查询每个服务。

无论哪种方式,您的数据包都需要一些问题信息。谷歌的DNS数据包结构,这里是一个快速指南的PTR请求-

id - 2字节,始终为零标志- 2字节,请求为零问题计数- 2字节,在本例中为1回答计数- 2字节,零权限计数- 2字节,零附加计数- 2字节,零

接下来是你的问题-名称(如_port ._tcp.local) -格式为3www6google3com0type - 2字节,PTR类型为12Class - 2字节,1用于Internet Class

应该做这件事。

但是,请注意,在您遇到这个麻烦之前,请查看是否可以将()绑定到端口5353。它不让我这样做,说地址正在使用中。我猜想那些将MDNS响应器移植到iOS的人忘记在他们的套接字上设置"重用地址"选项。这就是它的结尾。谢谢。

最新更新