【问题标题】:UDP WinSock - Not Receiving Broadcast PacketsUDP WinSock - 不接收广播数据包
【发布时间】:2016-12-07 16:14:16
【问题描述】:

我正在测试一个简单的套接字设置,其中服务器侦听指定端口,客户端发送该服务器应接收的广播数据包。

此设置在直接发送消息(即不广播)时可以正常工作,但在广播数据包时服务器永远不会收到。

部分代码(为简单起见,删减了错误检查):

// 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,但我会再试一次,看看是否有帮助。

标签: c++ c udp winsock broadcasting


【解决方案1】:

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

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

有关解释和可能的修复方法,请参阅以下内容: https://github.com/dechamps/WinIPBroadcast

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

【讨论】:

  • 我尝试禁用除一个网络适配器以外的所有网络适配器,但结果是一样的——数据包永远不会被接收到。这个问题是否也会影响本地测试(即客户端和服务器在同一进程的不同线程中运行)?
  • @yothsoggoth 我认为我在本地没有问题,但我正在使用 2 个不同的进程进行测试。我不确定同一应用程序的 2 个线程的行为是什么。如果您还没有使用它进行调试,我只能建议使用 Wireshark。
猜你喜欢
  • 2011-03-02
  • 2016-11-01
  • 1970-01-01
  • 2021-08-02
  • 1970-01-01
  • 2023-03-23
  • 2011-04-25
  • 1970-01-01
相关资源
最近更新 更多