SSDP和接口IP地址
问题描述:
我在写一个UPnP AV/DLNA DMS需要发送和接收SSDP消息。为了响应一些M-SEARCH
数据包,我需要发送一个回复,其中包含一个资源的URL(本例中为HTTP服务器),我选择该资源绑定到INADDR_ANY
(0.0.0.0
)。当然这个地址对于M-SEARCH
数据包的发送者来说是毫无意义的:接收到M-SEARCH
的接口的地址是最合适的。SSDP和接口IP地址
如何确定在回复数据包中发送的适当地址?
有些想法我已经考虑是:
- 绑定不同的接收器每个插槽。当接收者获得一个
M-SEARCH
数据包时,回复地址可以在回复中使用套接字的本地地址。但是,这需要知道并遍历所有接口,并根据接口可用性的变化添加和删除接收器。 - 把一个接收器放在
INADDR_ANY
上,迭代接口掩码来确定可能的源。但是,多个接口可能共享相同的子网。 - 接收到数据包后,提取数据包IP目标地址。这将是IP特定的,并可能在网络抽象的某处丢失。
答
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)
考察struct sockaddr_storage
me
您的IP地址。因为这些是通用接口,所以它可以用于IPv4或IPv6地址。
SSDP通过UDP ...不知道你说的是适用的。 – 2011-03-04 16:25:39
@Matt Joiner:啊,我在*页面看到很多“HTTP”提及,并认为它是TCP。您可以连接UDP套接字,然后在连接的套接字上使用'getsockname(2)'。我不确定未连接的套接字,但连接套接字并不可怕。 – sarnold 2011-03-06 09:33:36
这似乎工作。我应该重新解释这个问题,重点关注UDP。 – 2011-03-07 01:00:29