![](/img/trans.png)
[英]Computers on LAN do not consistently receive a UDP broadcast to 255.255.255.255 using boost::asio C++
[英]Receiving broadcast packet addressed to 255.255.255.255 in C++
我有一个通过将广播数据包发送到端口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屏幕截图可证明正在发送数据包:
从wireshark输出中可以看到,特殊设备正在使用广播进行通信,并将使用与源和目标相同的端口号。
正常的套接字通信将需要使用匹配的端口号,但是广播消息无法在同一套接字上交换,尤其是当端口号与wireshark不一致时。
通常,可以在255.255.255.255( INADDR_BROADCAST
)上进行绑定,但是可能会受到操作系统特权和权限的限制。
您可以尝试使用两个套接字来解决该问题-一个用于接收,另一个用于发送。 当然,必须先设置监听套接字,并将其绑定到0.0.0.0( INADDR_ANY
)和端口4930。在这种情况下,没有简单的方法可以按目标地址进行过滤(因为我在注释中写错了),因为大多数标准套接字API没有提供从套接字获取目标地址的方法。 在Linux上有一个例外IP_PKTINFO
上的SOL_IP
...
通过使用recvfrom,您将获得响应设备的源单播地址。 您必须注意,如果您的网络上有不止一个这样的设备,您将获得不止一个响应。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.