在C ++中接收寻址到255.255.255.255的广播包

时间:2014-02-07 01:44:55

标签: c++ c sockets networking

我有一个设备是通过在端口4930上向255.255.255.255发送广播数据包而发现的,设备通过在端口4930上将数据包发送回255.255.255.255来响应。

我有一段C ++代码可以在端口4930(源端口和目标端口)上发送数据包到255.255.255.255,但它无法从广播地址255.255.255.255接收数据包。

我可以看到设备工作正常,wireshark可以看到数据包来回传输,设备提供的专有软件可以很好地发现设备,问题出在C ++程序上,所以请继续关注响应。

现在,正如我所说,我可以发送一个数据包,但首先我无法绑定到IP地址255.255.255.255来接收数据包。我可以将组播地址更改为239.255.255.250,套接字将绑定但我需要地址255.255.255.255。

我的代码片段如下,我使用的是VC ++ 2010

bool CPTUProgramDlg::FindPTU(u_short port, const char * Destaddress){
    {
        //Data to send
        char packet_data[10] = {0x44,0x43,0x55,0x44,0x5f,0x50,0x49,0x4e,0x47,0x00};
        int packet_size=10;

        SOCKET sock;
        struct sockaddr_in addr;

        sock = socket(AF_INET, SOCK_DGRAM, 0);

        // set SO_BROADCAST on a socket to true (1): (so we can transmit to 255 addr)
        //In order to use broadcast the options of socket must change
        char broadcastON = 1;
        setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &broadcastON, sizeof broadcastON);

        if (sock < 0)
            return false;

        addr.sin_family = AF_INET;
        addr.sin_port = htons(port);
        addr.sin_addr.s_addr = inet_addr(Destaddress); // Specify dest IP

        sendto(sock, packet_data, packet_size, 0, (struct sockaddr*)&addr, sizeof(addr));

        if (bind(sock,(struct sockaddr*) &addr,sizeof(addr)) != -1){
            char Buff[512];
            recv(sock,Buff,512,0);
        }

        closesocket(sock);
    }

    return 1;
}

Wireshark屏幕截图,用于证明正在发送数据包:

enter image description here

1 个答案:

答案 0 :(得分:4)

从wireshark输出中看到特殊设备正在使用广播进行通信,并将使用相同的端口号作为源和目的地。

正常的套接字通信需要使用匹配的端口号,但广播消息不能通过同一个套接字交换,尤其是当端口号与wireshark不匹配时。

255.255.255.255(INADDR_BROADCAST)上的绑定通常可以正常工作,但可能会受到您的操作系统权限和权限的限制。

您可以尝试使用两个插槽解决问题 - 一个用于接收,另一个用于发送。当然,必须首先设置侦听套接字并将其绑定到0.0.0.0(INADDR_ANY)和端口4930.在这种情况下,没有简单的方法按目标地址进行过滤(因为我在评论中写错了)因为大多数标准套接字API都没有提供从套接字获取目标地址的方法。在Linux上有一个例外 - IP_PKTINFOSOL_IP ...

通过使用recvfrom,您将获得响应设备的源单播地址。您必须注意,如果您的网络上有更多这样的设备,您将收到多个响应。