2014-03-04 3 views
0

멀티 캐스트 그룹에 서비스 포트를 알리는 간단한 UDP 서버를 쓰려고하는데 멀티 캐스트가 작동하는 데 문제가 있습니다. 나는 Microsoft 문서를 둘러 보았고 복사/붙여 넣기를했지만 작동하지 않습니다. 문제가되는 코드는 다음과 같습니다.setsockopt returns error 10014

this->port = srvc_port; //11129 in my example 
    this->mcast_port = mcast_port; //11130 in my example 
    this->mcast_ip = mcast_ip; //230.0.0.30 in my example 

    int iResult = WSAStartup(MAKEWORD(2,2), &service_wsaData); 
    if (iResult != NO_ERROR) 
    { 
     cout << "WSAstartup failed" << endl; 
     return -1; 
    } 

    service_sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); 
    if (service_sock == INVALID_SOCKET) { 
     closesocket(service_sock); 
     WSACleanup(); 
     cout << "Error at socket" << endl; 
     return -1; 
    } 

    mcast_sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); 
    if(mcast_sock == INVALID_SOCKET) { 
     closesocket(mcast_sock); 
     WSACleanup(); 
     cout << "Error at socket" << endl; 
     return -1; 
    } 

    multicast.sin_family = AF_INET; // multicast is a sockaddr_in struct 
    multicast.sin_addr.s_addr = INADDR_ANY; 
    multicast.sin_port = htons(mcast_port); 

    service.sin_family = AF_INET; //same for service 
    service.sin_addr.s_addr = INADDR_ANY; 
    service.sin_port = htons(port); 

    if(::bind(service_sock, (sockaddr *)&service, sizeof(service)) == SOCKET_ERROR) { 
     closesocket(mcast_sock); 
     closesocket(service_sock); 
     WSACleanup(); 
     cout << "Error binding service socket" << endl; 
     return -1; 
    }; 

    if(::bind(mcast_sock, (sockaddr *)&multicast, sizeof(multicast)) == SOCKET_ERROR) { 
     closesocket(mcast_sock); 
     closesocket(service_sock); 
     WSACleanup(); 
     cout << "Error binding multicast socket" << endl; 
     return -1; 
    }; 

    mreq.imr_multiaddr.s_addr = inet_addr(mcast_ip.c_str()); //mreq is declared like so "struct ip_mreq mreq;" in the class 
    mreq.imr_interface.s_addr = htonl(INADDR_ANY); 

    if(setsockopt(mcast_sock,IPPROTO_IP,IP_ADD_SOURCE_MEMBERSHIP,(char *) &mreq, sizeof(mreq)) == SOCKET_ERROR) 
    { 
      //I get error 10014 here 
     cout << "Error: " << WSAGetLastError() << endl; 
     return -1; 
    } 

아무 도움이됩니다.

+0

음, 의사는 10014가 잘못된 주소임을 의미합니다. 우리는 여러분의'mreq' 변수와 그것의 초기화로부터 많은 것을 보지 못합니다. 여기서는 오직 3 명의 멤버 중 2 명만 초기화합니다. 소켓 프로그래밍의 경우에는 0으로 memsetting하여 이러한 구조의 초기화를 시작하는 것이 현명합니다. – pasztorpisti

답변

2

10014은 의미 WSAEFAULT는 "버퍼가 optval이 매개 변수는 프로세스 주소 공간 또는 너무 작은 optlen을 파라미터의 유효 부분이 아닌 가리키는."

가 문서를 읽고 :

IPPROTO_IP Socket Options

IP_ADD_SOURCE_MEMBERSHIPip_mreq_source 구조에 대한 포인터를 기대 :

typedef struct ip_mreq_source { 
    struct in_addr imr_multiaddr; 
    struct in_addr imr_sourceaddr; 
    struct in_addr imr_interface; 
} IP_MREQ_SOURCE, *PIP_MREQ_SOURCE; 

하기는 대신 ip_mreq 구조에 그것을 포인터를 전달됩니다

typedef struct ip_mreq { 
    struct in_addr imr_multiaddr; 
    struct in_addr imr_interface; 
} IP_MREQ, *PIP_MREQ; 

ip_mreqip_mreq_source보다 작은, 따라서 sizeof(mreq)IP_ADD_SOURCE_MEMBERSHIP 너무 작습니다. mreq 변수를 ip_mreq_source으로 변경하고 imr_sourceaddr 회원을 입력해야합니다.

ip_mreqIP_ADD_MEMBERSHIPIP_DROP_MEMBERSHIP으로 사용됩니다.

ip_mreq_sourceIP_ADD_SOURCE_MEMBERSHIP, IP_DROP_SOURCE_MEMBERSHIP, IP_BLOCK_SOURCEIP_UNBLOCK_SOURCE 사용된다.