只有通過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);
- }
- }