我的网络知识有限,当领导通知要开发一个udp广播通信时,心想这还不简单,于是快速的写了代码
//---------------------------------------------
// Create a socket for sending data
SendSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
//---------------------------------------------
// Set up the RecvAddr structure with the IP address of
// the receiver (in this example case "123.456.789.1")
// and the specified port number.
RecvAddr.sin_family = AF_INET;
RecvAddr.sin_port = htons(Port);
RecvAddr.sin_addr.s_addr = inet_addr("255.255.255.255");
//---------------------------------------------
// Send a datagram to the receiver
printf("Sending a datagram to the receiver...\n");
strcpy(SendBuf, "I 'm bixiangyang.");
int i = sendto(SendSocket,
SendBuf,
strlen(SendBuf) + 1,
0,
(SOCKADDR *) &RecvAddr,
sizeof(RecvAddr));
if (i == SOCKET_ERROR)
{
cout<<"Error code "<<WSAGetLastError()<<endl;
}
即向目标IP255.255.255.255发送udp数据包,但是接受程序并未收到。排查得知sendto返回了错误,WSAGetLastError()返回了错误码10013。翻查文档得知必须设置
socket属性SO_BROADCAST,于是在创建完socket后调用如下语句,接受程序收到广播信息。
bool bOpt = true;
//设置该套接字为广播类型
setsockopt(SendSocket, SOL_SOCKET, SO_BROADCAST, (char*)&bOpt, sizeof(bOpt));
后再经调研,发现广播地址255.255.255.255是受限的广播地址,其数据包不被路由器转发,该地址用于主机配置过程中IP数据报的目的地址,此时,主机可能还不知道它所在网络的网络掩码,甚至连它的IP地址也不知道。在任何情况下,路由器都不转发目的地址为受限的广播地址的数据报,这样的数据报仅出现在本地网络中。
正确的广播地址应该为指向子网的广播,及主机号为全1且有特定子网号的地址,例如某台主机为192.168.16.80,子网掩码为255.255.255.0,则其子网广播地址为192.168.16.255,这种数据包可以被路由,它会经由路由器到达本网段内的所有主机,此种广播也叫直接广播;如果想在整个网络中广播数据,要向255.255.255.255发送数据包,这种数据包不会被路由,它只能到达本物理网络中的所有主机,此种广播叫有限广播。
请注意,使用子网广播地址不需要设置SO_BROADCAST属性。
对于广播地址255.255.255.255如何使用,请参考DHCP协议。
若将广播地址设为指向所有子网的广播地址,例如192.168.255.255,sendto函数提示发送正确,但是接收程序并未收到此数据包,不了解。