setsockopt возвращает ошибку 10014

Я пытаюсь написать простой UDP-сервер, который рекламирует свой сервисный порт в группе многоадресной рассылки, но у меня возникают проблемы с работой многоадресной рассылки. Я попытался просмотреть документацию Microsoft и скопировать / вставить часть их кода, но это не работает. Вот проблемный код:

    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 является WSAEFAULT, что значит «Буфер, на который указывает параметр optval, не находится в допустимой части адресного пространства процесса или параметр optlen слишком мал.«

Прочитайте документацию:

Опции сокета IPPROTO_IP

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_mreq меньше чем ip_mreq_sourceтаким образом sizeof(mreq) слишком мал для IP_ADD_SOURCE_MEMBERSHIP, Вы должны изменить свой mreq переменная к ip_mreq_sourceи обязательно заполните его imr_sourceaddr член.

ip_mreq используется для IP_ADD_MEMBERSHIP а также IP_DROP_MEMBERSHIP,

ip_mreq_source используется для IP_ADD_SOURCE_MEMBERSHIP, IP_DROP_SOURCE_MEMBERSHIP, IP_BLOCK_SOURCE, а также IP_UNBLOCK_SOURCE,

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]