2014-07-24 6 views
1

저는 3 개의 네트워크 인터페이스를 가진 컴퓨터를 가지고 있습니다. 하나는 실제 컴퓨터이고 다른 하나는 VMWare 가상 컴퓨터입니다. 포트 1900에서 UPNP 장치로부터 멀티 캐스트 메시지를 수신하고 싶습니다.UDP 멀티 캐스트가 내 소켓에서 수신되지 않는 이유는 무엇입니까?

모든 어댑터를 열거하고 어댑터 당 하나의 소켓을 만듭니다. 또한 소켓 옵션 ReuseAddr을 설정하고 ExclusiveAddrUse 소켓 옵션을 해제하고 각 소켓을 멀티 캐스트 그룹 239.255.255.250에 추가합니다. 그리고 나는 소켓을 addr에 바인딩합니다. InterfaceAddr : 1900

문제는 하나의 소켓 만 메시지를 수신한다는 것입니다. 하나의 VMWare net 소켓 중 하나입니다. 표시

Proto Local address   Peer address       PID App 
UDP 0.0.0.0:1900   *:*         5248 uTorrent 
UDP 127.0.0.1:1900   *:*         3932 myApp 
UDP 127.0.0.1:1900   *:*         1400 svchost 
UDP 192.168.0.100:1900  *:*         3932 myApp 
UDP 192.168.0.100:1900  *:*         1400 svchost 
UDP 192.168.139.1:1900  *:*         1400 svchost 
UDP 192.168.139.1:1900  *:*         3932 myApp  + 
UDP 192.168.180.1:1900  *:*         1400 svchost 
UDP 192.168.180.1:1900  *:*         3932 myApp 

만 소켓이 '+'UPNP 멀티 캐스트를 수신 : netstat -a -o -p UDP >netstat.txt 내 모든 소켓이 듣고있는 것을 저에게 보여줍니다. 그러나 Wireshark는 나에게 수신되지 않는 다른 많은 패킷이 있다는 것을 알려줍니다. 내 잘못은 어디 갔지?

UPD1 내 코드가 호스트 (Windows 7)에서 실행 중이며 그 시점에 실행중인 가상 컴퓨터가 없습니다. 나는 실제 net - 192.168.0. *에 UPNP 장치 (라우터 등)를 가지고 있습니다. * 또한 일부 알림을 보내지 만받을 수는 없습니다. 가상 네트워크 192.168.139. *를 통해 UPNP NOTIFY 메시지가 호스트 (ms 플레이어/렌더러/etc)에 의해 전송됩니다. 이러한 알림은 사용 가능한 모든 네트워크를 통해 전송되지만 192.168.139.1 인터페이스에서만 수신됩니다.

UPD2 단일 소켓을 사용하고 INADDR_ANY : 1900에 바인딩하도록 코드를 다시 작성합니다. 처음으로 새 버전을 시작하면 정상적으로 작동합니다. 가상 또는 실제 네트워크를 통해 모든 장치에서 모든 UPNP 메시지를받습니다. 그러나 다음에 응용 프로그램을 시작하면 192.168.139. * net의 알림 만 수신된다는 것을 알 수 있습니다. 모두 시작 질문과 같습니다.

UPD3 모든 가상 네트워크 어댑터를 끄고 실제 어댑터 만 유지합니다. 이 구성에서 두 버전의 코드 (하나의 소켓이 모든 주소에 바인드 됨/인터페이스 당 하나의 소켓)가 올바르게 작동합니다.

약 MCVE MCVE를 만드는 것은 그렇게 쉽지가 않아서, 이제는 어떤 현상이 발생하는지 이해하려고 노력하고 있습니다.

의사 내가 (여기 - http://www4.ncsu.edu/~rhee/clas/csc495j/mcast.api.txt) 멀티 캐스팅에 대해 다음 메모를 발견

hSock = :: socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); 

u_long nb = 1; 
::ioctlsocket(hSock, FIONBIO, &nb); 

reuseAddrSet(hSock, TRUE); 
reusePortSet(hSock, TRUE); 

if (useSingleSocket) 
    bindSocket(hSock, "any-addr"); 
else 
    bindSocket(hSock, "interface-addr"); 

broadcastModeSet(hSock, TRUE); 

setSockOption(hSock, IPPROTO_IP, IP_ADD_MEMBERSHIP, { "any-addr", "239.255.255.250" }); 

UPD4 코드 :

모든 회원은 하나의 인터페이스와 연결된, 그것은 가능 입니다

하나 이상의 인터페이스에서 같은 그룹에 가입하십시오. 기본 멀티 캐스트 인터페이스를 선택하려면 "imr_interface"를 INADDR_ANY로 지정하고 (멀티 캐스트 가능) 인터페이스를 선택하려면 호스트의 로컬 주소 중 하나를 선택해야합니다. 최대 IP_MAX_MEMBERSHIPS (현재 20 개) 개의 멤버쉽을 단일 소켓에 추가 할 수 있습니다. I 처음으로 가정

로서 만 모든 인터페이스의 멀티 캐스트 그룹에의 인터페이스, 그리고 기본 추가로 상기 주 코드

setSockOption(hSock, IPPROTO_IP, IP_ADD_MEMBERSHIP, { "any-addr", "239.255.255.250" } 

따랐다.그래서, 난 인터페이스를 열거 형 단일 소켓

setSockOption(hSock, IPPROTO_IP, IP_ADD_MEMBERSHIP, { "interface-addr", "239.255.255.250" } 

전화하거나 soxket을 결합하는 데 사용되는 것과 동일한 주소로 각 인터페이스 별 소켓을 호출해야합니다.

맞습니까?

+0

이 코드가 VMWare 호스트 또는 클라이언트에서 실행되고 있습니까? 어떤 가상 네트워크 인터페이스입니까? 브리지, 호스트 전용 또는 NAT? –

+0

로컬 어댑터에 소켓을 만들고 바인딩 한 실제 코드를 표시 한 다음 멀티 캐스트 그룹에 등록하십시오. –

+0

어댑터 당 소켓이 필요하지 않습니다. 모든 어댑터를 통해 멀티 캐스트 그룹에 가입하고 소켓을 0.0.0.0에 바인딩하면됩니다. – EJP

답변

-1

소켓 사용자는 UPD4로 작성된대로 인터페이스 주소를 사용하여 멀티 캐스트 그룹에 소켓을 추가해야합니다. 멀티 캐스트 그룹에 소켓을 추가 할 때 INADDR_ANY를 사용하면 기본 멀티 캐스트 인터페이스 만 멀티 캐스트 그룹에 추가되므로 하나의 인터페이스 만 멀티 캐스트 메시지를 수신 할 수 있습니다.

우리가 알다시피 소켓의 멀티 캐스트 그룹 수에 대한 OS 제한이 있으므로 더 좋은 방법은 각 네트워크 인터페이스마다 하나의 소켓을 만드는 것입니다.

+0

* * 정확하게 쓰여진 부분은 어디입니까? 나는 그것을 본 적이 없다. '기본 멀티 캐스트 인터페이스'에 대한 귀하의 논란은 올바르지 않습니다. 부분적으로 그런 것이 없기 때문입니다. 모든 인터페이스를 통해 멀티 캐스트 그룹에 가입 할 수 있으며, 모든 인터페이스를 통해 자주 참여해야합니다. – EJP

+0

위의 내용을 준수하도록 코드를 다시 작성하면 작동이 시작됩니다. 이것은 내가 생각하는 주요 기준입니다. –

+0

어딘가에 '쓰여졌다'는 주장을하고 인용문을 제공하여 그것을 구체화하라는 요구가 나올 때 아이디어는 당신이 그렇게하거나 철회한다는 것입니다. 코드가 작동한다는 사실은 어디서나 '쓰여졌다'는 것을 증명하지 못합니다. 내 주장을 뒷받침하는 코드도 있지만 어디에도 '쓰여졌다'고 주장하지는 않습니다. 그러나 그것은 당신의 방식대로 이루어져야한다는 귀하의 주장을 반증합니다. – EJP