【问题标题】:SSDP and interface IP addressSSDP 和接口 IP 地址
【发布时间】:2011-03-04 12:08:23
【问题描述】:

我正在写一个UPnP AV/DLNA DMS,它需要发送和接收SSDP 消息。为了响应一些M-SEARCH 数据包,我需要发送带有资源(在本例中为HTTP 服务器)的URL 的回复,我选择将其绑定到INADDR_ANY (0.0.0.0)。当然这个地址对于M-SEARCH包的发送者来说是没有意义的:接收M-SEARCH的接口地址是最合适的。

如何确定要在回复包中发送的适当地址?

我考虑过的一些想法是:

  1. 将不同的接收器绑定到每个套接字。当接收方收到M-SEARCH 数据包时,回复地址可以在回复中使用套接字的本地地址。但是,这需要了解和迭代所有接口,并随着接口可用性的变化添加和删除接收器。
  2. INADDR_ANY 上放置一个接收器,并迭代接口网络掩码以确定可能的来源。但是,多个接口可能共享同一个子网。
  3. 在收到数据包时提取 IP 目标地址。这将是特定于 IP 的,并且可能会在网络抽象的某个地方丢失。

【问题讨论】:

    标签: linux upnp dlna network-interface ssdp


    【解决方案1】:

    getsockname(2) 后跟 getnameinfo(3) 报告您的 TCP/IP 堆栈已分配给套接字的 IP 地址。 (很明显,如果服务器和客户端位于 NAT 系统的另一侧,这与客户端可以使用的内容不匹配;在这种情况下,也许有聪明的 UPnP 技巧来发现客户端可以用来联系服务器的 IP 地址.)

    我假设您的服务器看起来像这样:

    lfd = socket();
    ret = bind(lfd,...);
    connection = listen(lfd, 10);
    /* add connection to your select queue or poll queue */
    

    你可以附加类似这样的代码:

    struct sockaddr_storage me;
    socklen_t *len = sizeof(me);
    char name[40];
    ret = getsockname(connection, &me, &len);
    ret = getnameinfo(&me, &len, name, sizeof(name), NULL, 0, NI_NUMERICHOST);
    

    getnameinfo(3) 检查您的 IP 地址的 struct sockaddr_storage me。因为这些是通用接口,所以它适用于 IPv4 或 IPv6 地址。

    【讨论】:

    • SSDP 通过 UDP...不确定你说的是否适用。
    • @Matt Joiner:啊,我在 Wikipedia 页面上看到很多“HTTP”提及,并假设它是 TCP。您可以连接 UDP 套接字,然后在连接的套接字上使用 getsockname(2)。我不太确定未连接的套接字,但连接套接字并不可怕。
    • 这似乎有效。我应该重新表述这个问题以关注 UDP。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-03-14
    • 2010-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多