2011-03-04 8 views
3

UPnP AV/DLNA DMS을 작성 중이므로 SSDP 메시지를 보내고 받으십시오. 어떤 M-SEARCH 패킷에 대한 응답으로 나는 INADDR_ANY (0.0.0.0)에 바인드하기로 선택한 리소스 (이 경우 HTTP 서버)의 URL로 응답을 보내야합니다. 물론이 주소는 M-SEARCH 패킷의 발신자에게는 의미가 없습니다. M-SEARCH이 수신 된 인터페이스의 주소가 가장 적합합니다.SSDP 및 인터페이스 IP 주소

회신 패킷에 보낼 적절한 주소를 어떻게 결정합니까? 내가 생각했습니다

몇 가지 아이디어가 있습니다 :

  1. 각 소켓에 다른 수신기를 바인딩. 수신자가 M-SEARCH 패킷을 받으면 응답 주소는 응답에서 소켓의 로컬 주소를 사용할 수 있습니다. 그러나이를 위해서는 모든 인터페이스에 대한 정보를 알고 반복해야하며 인터페이스 가용성이 변경됨에 따라 수신기를 추가 및 제거해야합니다.
  2. INADDR_ANY에 단일 수신기를 놓고 인터페이스 netmasks를 반복하여 가능한 소스를 결정하십시오. 그러나 하나 이상의 인터페이스가 동일한 서브넷을 공유 할 수 있습니다.
  3. 수신시 패킷 IP 대상 주소를 추출하십시오. 이는 특정 IP 일 수 있으며 네트워크 추상화 어딘가에서 사라질 수 있습니다.

답변

2

getsockname(2) 다음에 getnameinfo(3)은 TCP/IP 스택이 소켓에 할당 한 IP 주소를보고합니다. (분명히 이것은 서버와 클라이언트가 NAT 시스템의 반대쪽에있는 경우 클라이언트가 사용할 수있는 것과 일치하지 않을 것입니다.이 경우 클라이언트가 서버에 접속할 때 사용할 수있는 IP 주소를 찾는 영리한 UPnP 속임수가있을 것입니다 . 당신이 유사한 코드를 추가 할 수

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_storageme을 검사)

나는 당신의 서버가이 같이 보입니다 가정 주소. 이러한 인터페이스는 일반적인 인터페이스이기 때문에 IPv4 또는 IPv6 주소에서 작동합니다.

+0

SSDP가 UDP를 초과했습니다 ... 귀하가 말한 내용이 적용 가능한지 확실하지 않습니다. –

+1

@Matt Joiner : 아, Wikipedia 페이지에서 많은 "HTTP"언급을보고 TCP라고 가정합니다. UDP 소켓을 연결 한 다음 연결된 소켓에서'getsockname (2)'을 사용할 수 있습니다. 연결되지 않은 소켓에 대해서는 확신이 없지만 소켓 연결은 끔찍한 것이 아닙니다. – sarnold

+0

이 작동하는 것 같습니다. 나는 UDP에 중점을 두어 질문을 다시 말해야한다. –