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"); } } 

(应该是评论,但我的声誉不够高)

我不知道这是否适用于您,但在最新版本的Windows上广播有一种不直观的行为。 如果您有多个物理以太网适配器,则只会在“首选”接口上接收广播(其中“首选项”由Windows路由表确定)

请参阅以下内容以获取解释和可能的解决方法: https : //github.com/dechamps/WinIPBroadcast

另一个临时修复方法是禁用所有其他网络适配器,以确保在正确的网络适配器上接收广播(在控制面板/网络和共享中心/更改适配器设置中)。