Я тестирую простую установку сокета, в которой сервер прослушивает указанный порт, а клиент отправляет широковещательный пакет, который должен быть получен этим сервером.UDP WinSock - не принимать пакеты широковещания
Эта настройка работает нормально при отправке сообщений напрямую (то есть не в режиме широковещания), но при широковещательном рассылке пакет никогда не принимается на сервере.
Часть кода (подстриженной вниз с проверки ошибок удалена для простоты):
// Client (broadcast sender)
// Create and bind the client socket
clientSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
sockaddr_in sockAddr;
sockAddr.sin_family = AF_INET;
sockAddr.sin_port = htons(5678);
sockAddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
bind(clientSocket, (sockaddr*)(&sockAddr), sizeof(sockAddr));
u_long uMode = 1;
ioctlsocket(clientSocket, FIONBIO, &uMode);
char broadcast = 1;
setsockopt(clientSocket, SOL_SOCKET, SO_BROADCAST, &broadcast, sizeof(broadcast));
// ...
// Send the packet
sockaddr_in sockAddress;
sockAddress.sin_family = AF_INET;
sockAddress.sin_addr.S_un.S_addr = htonl(INADDR_BROADCAST);
sockAddress.sin_port = htons(5679);
char const* pPacket = "Test";
size_t uPacketSize = strlen(pPacket) + 1;
sendto(clientSocket, pPacket, (int)uPacketSize, 0, (sockaddr*)&sockAddress, sizeof(sockAddress));
-
// Server (listener)
// Create and bind the server socket
serverSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
sockaddr_in sockAddr;
sockAddr.sin_family = AF_INET;
sockAddr.sin_port = htons(5679);
sockAddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
bind(serverSocket, (sockaddr*)(&sockAddr), sizeof(sockAddr));
u_long uMode = 1;
ioctlsocket(serverSocket, FIONBIO, &uMode);
// ...
char pBuffer[1024];
while (true)
{
int iRecvSize = recv(serverSocket, pBuffer, 1024, 0);
if (iRecvSize)
{
printf("Received packet\n");
}
}
Возможно, вы захотите добавить проверку ошибок для большего количества функций, таких как, например, вызовы 'setsockopt'. –
Вы * также * необходимо установить опцию 'SO_BROADCAST' в сокет, который вы хотите * принять * в эфир. –
@Someprogrammerdude У меня есть проверка ошибок в фактическом коде, я просто удалил его для этого вопроса. Ни одна из функций не возвращает никаких ошибок (за исключением случайного WSAEWOULDBLOCK, который следует ожидать для неблокирующих сокетов). Я думаю, что я попытался установить SO_BROADCAST на ресивер, но я попробую еще раз и посмотрю, поможет ли это. – yothsoggoth