使用UDP協議進行信息的傳輸之前不需要建議連接。換句話說就是客戶端向服務器發送信息,客戶端只需要給出服務器的ip地址和端口號,然後將信息封裝到一個待發送的報文中並且發送出去。至於服務器端是否存在,或者能否收到該報文,客戶端根本不用管。
單播用於兩個主機之間的端對端通信,廣播用於一個主機對整個局域網上所有主機上的數據通信。單播和廣播是兩個極端,要麼對一個主機進行通信,要麼對整個局域網上的主機進行通信。實際情況下,經常需要對一組特定的主機進行通信,而不是整個局域網上的所有主機,這就是多播的用途。
通常我們討論的udp的程序都是一對一的單播程序。本章將討論一對多的服務:廣播(broadcast)、多播(multicast)。對於廣播,網絡中的所有主機都會接收一份數據副本。對於多播,消息只是發送到一個多播地址,網絡知識將數據分發給哪些表示想要接收發送到該多播地址的數據的主機。總得來說,只有UDP套接字允許廣播或多播。
一、UDP廣播
廣播UDP與單播UDP的區別就是IP地址不同,廣播使用廣播地址255.255.255.255,將消息發送到在同一廣播網絡上的每個主機。值得強調的是:本地廣播信息是不會被路由器轉發。當然這是十分容易理解的,因為如果路由器轉發了廣播信息,那麼勢必會引起網絡癱瘓。這也是為什麼IP協議的設計者故意沒有定義互聯網范圍的廣播機制。
廣播地址通常用於在網絡游戲中處於同一本地網絡的玩家之間交流狀態信息等。
其實廣播顧名思義,就是想局域網內所有的人說話,但是廣播還是要指明接收者的端口號的,因為不可能接受者的所有端口都來收聽廣播。
UDP服務端代碼:
1 #include<iostream> 2 #include<stdio.h> 3 #include<sys/socket.h> 4 #include<unistd.h> 5 #include<sys/types.h> 6 #include<netdb.h> 7 #include<netinet/in.h> 8 #include<arpa/inet.h> 9 #include<string.h> 10 using namespace std; 11 int main() 12 { 13 setvbuf(stdout,NULL,_IONBF,0); 14 fflush(stdout); 15 int sock=-1; 16 if((sock=socket(AF_INET,SOCK_DGRAM,0))==-1) 17 { 18 cout<<"sock error"<<endl; 19 return -1; 20 } 21 const int opt=-1; 22 int nb=0; 23 nb=setsockopt(sock,SOL_SOCKET,SO_BROADCAST,(char*)&opt,sizeof(opt));//設置套接字類型 24 if(nb==-1) 25 { 26 cout<<"set socket error...\n"<<endl; 27 return -1; 28 } 29 struct sockaddr_in addrto; 30 bzero(&addrto,sizeof(struct sockaddr_in)); 31 addrto.sin_family=AF_INET; 32 addrto.sin_addr.s_addr=htonl(INADDR_BROADCAST);//套接字地址為廣播地址 33 addrto.sin_port=htons(6000);//套接字廣播端口號為6000 34 int nlen=sizeof(addrto); 35 while(1) 36 { 37 sleep(1); 38 char msg[]={"the message broadcast"}; 39 int ret=sendto(sock,msg,strlen(msg),0,(sockaddr*)&addrto,nlen);//向廣播地址發布消息 40 if(ret<0) 41 { 42 cout<<"send error...\n"<<endl; 43 return -1; 44 } 45 else 46 { 47 printf("ok\n"); 48 } 49 } 50 return 0; 51 }
UDP廣播客戶端代碼:
1 #include<iostream> 2 #include<stdio.h> 3 #include<sys/socket.h> 4 #include<unistd.h> 5 #include<sys/types.h> 6 #include<netdb.h> 7 #include<netinet/in.h> 8 #include<arpa/inet.h> 9 #include<string.h> 10 11 12 using namespace std; 13 int main() 14 { 15 setvbuf(stdout,NULL,_IONBF,0); 16 fflush(stdout); 17 struct sockaddr_in addrto; 18 bzero(&addrto,sizeof(struct sockaddr_in)); 19 addrto.sin_family=AF_INET; 20 addrto.sin_addr.s_addr=htonl(INADDR_ANY); 21 addrto.sin_port=htons(6000); 22 socklen_t len=sizeof(addrto); 23 int sock=-1; 24 if((sock=socket(AF_INET,SOCK_DGRAM,0))==-1) 25 { 26 cout<<"socket error..."<<endl; 27 return -1; 28 } 29 const int opt=-1; 30 int nb=0; 31 nb=setsockopt(sock,SOL_SOCKET,SO_BROADCAST,(char*)&opt,sizeof(opt)); 32 if(nb==-1) 33 { 34 cout<<"set socket errror..."<<endl; 35 return -1; 36 } 37 if(bind(sock,(struct sockaddr*)&(addrto),len)==-1) 38 { 39 cout<<"bind error..."<<endl; 40 return -1; 41 } 42 char msg[100]={0}; 43 while(1) 44 { 45 int ret=recvfrom(sock,msg,100,0,(struct sockaddr*)&addrto,&len); 46 if(ret<=0) 47 { 48 cout<<"read error..."<<endl; 49 } 50 else 51 { 52 printf("%s\t",msg); 53 } 54 sleep(1); 55 } 56 return 0; 57 }
二、UDP多播