2014-03-04 79 views
0

我想寫一個簡單的UDP服務器,它在多播組上發佈它的服務端口,但我無法讓多播工作。我試着在Microsoft文檔中四處查看,並複製/粘貼了他們的一些代碼,但它不起作用。這裏是有問題的代碼:setsockopt返回錯誤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個成員中的3個。在套接字編程的情況下,它也可以通過將它們設置爲零來開始這些結構的初始化。 – pasztorpisti

回答

2

10014是WSAEFAULT,這意味着「指向的緩衝區由optval的參數不在進程的地址空間或optlen參數太小的有效部分。

閱讀文檔:

IPPROTO_IP Socket Options

IP_ADD_SOURCE_MEMBERSHIP期望的指針ip_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_mreq用於IP_ADD_MEMBERSHIPIP_DROP_MEMBERSHIP

ip_mreq_source用於IP_ADD_SOURCE_MEMBERSHIPIP_DROP_SOURCE_MEMBERSHIPIP_BLOCK_SOURCE,和IP_UNBLOCK_SOURCE