只有通过UDP套接字才能实现广播和多播。
报文的发送
在默认情况下,UPD套接字是无法发送广播报文的,套接字启用/禁止广播是通过SOL_SOCKET->SO_BROADCAST选项来完成的。
下面代码,可以确认广播选项是默认关闭的:
- BOOL bBroadcast;
- int optlen = sizeof(bBroadcast);
- if(SOCKET_ERROR==getsockopt(sock,SOL_SOCKET,SO_BROADCAST,
- (char*)&bBroadcast,&optlen))
- {
- HandleError("getsockopt");
- closesocket(sock);
- WSACleanup();
- return -1;
- }
- if(bBroadcast)
- {
- printf("广播默认打开\n");
- }
- else
- {
- printf("广播默认关闭\n");
- }
输出为 默认关闭,因此要发生广播报文,必须首先启用SO_BROADCAST选项,如下:
- bBroadcast = TRUE;
- optlen = sizeof(bBroadcast);
- if(SOCKET_ERROR==setsockopt(sock,SOL_SOCKET,SO_BROADCAST,
- (char*)&bBroadcast,optlen))
- {
- HandleError("setsockopt");
- closesocket(sock);
- WSACleanup();
- return -1;
- }
此时仍然可以调用getsockopt函数检查是否设置成功,成功的设置了SO_BROADCAST后,就可以发送广播报文了
- SOCKADDR_IN addr;
- memset(&addr,0,sizeof(SOCKADDR_IN));
- addr.sin_family=AF_INET;
- addr.sin_port=htons(5050);
- addr.sin_addr.s_addr=INADDR_BROADCAST;
- const char* msg="Hello! Broadcast Test";
- int len = strlen(msg);
- if(SOCKET_ERROR==sendto(sock,msg,len,0,
- (SOCKADDR*)&addr,sizeof(SOCKADDR_IN)))
- {
- HandleError("sendto");
- closesocket(sock);
- WSACleanup();
- return -1;
- }
winsock定义常量0xffffffff,对应于受限广播地址255.255.255.255。
广播报文的接收
- SOCKET sock = socket(AF_INET,SOCK_DGRAM,0);
- SOCKADDR_IN addr;
- memset(&addr,0,sizeof(SOCKADDR_IN));
- addr.sin_family=AF_INET;
- addr.sin_port=htons(5050);
- addr.sin_addr.s_addr=INADDR_ANY;
- bind(sock,(SOCKADDR*)&addr,sizeof(SOCKADDR_IN));
- int ret;
- char buf[5000];
- while(TRUE)
- {
- ret=recvfrom(sock,buf,5000,0,NULL,NULL);
- if(SOCKET_ERROR==ret)
- {
- printf("recvfrom:%d\n",WSAGetLastError());
- break;
- }
- else
- {
- printf("recvd %d bytes\n", ret);
- }
- }