Linux之广播和多播

来源:互联网 发布:阈值分割算法 编辑:程序博客网 时间:2024/06/06 04:58

最近学习Linux网络编程学到了广播与多播,就在这做点笔记。其中一些原理我就不介绍了,我觉得学习Linux网络编程,TCP/IP三卷还是基础,是需要好好看看。

广播的服务器端 :

[cpp] view plaincopy
  1. #include <sys/socket.h>  
  2. //#include <sys/inet.h>  
  3. #include <sys/ioctl.h>  
  4. #include <arpa/inet.h>  
  5. #include <stdio.h>  
  6. #include <time.h>  
  7.   
  8. #define BUFLEN 255  
  9.   
  10. void getcurtime(char *curtime)  
  11. {  
  12.     time_t tm = time(NULL);  
  13.     sprintf(curtime, "time : %d \n",tm);  
  14. }  
  15.   
  16. int main(int argc, char **argv)  
  17. {  
  18.     struct sockaddr_in peeraddr ;  
  19.     int sockfd;  
  20.     int optval = 1;  
  21.     char msg[BUFLEN+1];   
  22.   
  23.     if( argc != 3 )  
  24.     {  
  25.         perror("can't input ADDRESS and PORT \n");  
  26.         _exit(1);  
  27.     }  
  28.   
  29.     sockfd = socket(AF_INET, SOCK_DGRAM, 0);                            //设置套接字  
  30.     if( sockfd < 0 )   
  31.     {  
  32.         perror("socket fail \n");  
  33.         _exit(1);  
  34.     }  
  35.   
  36.     setsockopt(sockfd, SOL_SOCKET,SO_BROADCAST,&optval, sizeof optval);         //设置广播方式,SO_BROADCAST  
  37.     memset(&peeraddr, 0, sizeof(struct sockaddr_in) );  
  38.     peeraddr.sin_family = AF_INET ;  
  39.   
  40.     if( inet_aton(argv[1], &peeraddr.sin_addr) == 0 )  
  41.     {  
  42.         perror("inet_aton fail \n");  
  43.         _exit(1);  
  44.     }  
  45.   
  46.     peeraddr.sin_port = htons(atoi(argv[2]) );  
  47.     printf("-------------广播服务器启动------------\n");  
  48.     while(1)  
  49.     {  
  50.         getcurtime(msg);  
  51.         sendto(sockfd, msg, strlen(msg), 0, (struct sockaddr *)&peeraddr, sizeof (struct sockaddr) );  
  52.         //printf("sendto return %d  \n",a);  
  53.         fflush(stdout);   
  54.         sleep(3);  
  55.     }  
  56.   
  57.     return 1;  
  58.   
  59.   
  60. }  
下面是客户端 :

[cpp] view plaincopy
  1. #include <sys/types.h>  
  2. #include <sys/socket.h>  
  3. #include <arpa/inet.h>  
  4. #include <stdio.h>  
  5. #define BUFLEN 255  
  6.   
  7. int main(int argc, char **argv)  
  8. {  
  9.     struct sockaddr_in localaddr;  
  10.     int sockfd,n;  
  11.     char msg[BUFLEN+1];  
  12.   
  13.     if(argc != 2)  
  14.     {  
  15.         perror("port error \n");  
  16.         _exit(1);  
  17.     }  
  18.   
  19.     sockfd = socket(AF_INET, SOCK_DGRAM, 0);  
  20.     if( sockfd < 0)  
  21.     {  
  22.         perror("sock fail \n");  
  23.         _exit(1);  
  24.     }  
  25.       
  26.     localaddr.sin_port = htons(atoi(argv[1]) );  
  27.     localaddr.sin_addr.s_addr = htonl(INADDR_ANY);  
  28.   
  29.     int optval = SO_REUSEADDR ;  
  30.     setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &optval,sizeof optval);  
  31.       
  32.     if(bind(sockfd, (struct sockaddr *)&localaddr, sizeof (struct sockaddr) ) < 0 )  
  33.     {  
  34.         perror("bind fail \n");  
  35.         _exit(1);  
  36.     }  
  37.   
  38.     if( n = read(sockfd, msg,BUFLEN) == -1 )  
  39.     {  
  40.         perror("read error \n");  
  41.         _exit(1);  
  42.     }  
  43.     else  
  44.     {  
  45.         msg[n] = '0';  
  46.         printf("read time : %s \n",msg);  
  47.     }  
  48.     return 1;  
  49. }  
下面是多播,服务器端不需要太大的变动,只需要将广播工作方式去掉,发送地址指定为多播地址即可。但客户端需要加入多播组,没有加入多播组的客户端接受到数据报后就会丢弃。

[cpp] view plaincopy
  1. #include <sys/types.h>  
  2. #include <sys/socket.h>  
  3. #include <arpa/inet.h>  
  4. #include <stdio.h>  
  5. #define BUFLEN 255  
  6.   
  7. int main(int argc, char **argv)  
  8. {  
  9.     struct sockaddr_in localaddr;  
  10.     int sockfd,n;  
  11.     char msg[BUFLEN+1];  
  12.     struct ip_mreq mcaddr;          //D类多播地址结构体  
  13.     if(argc != 2)  
  14.     {  
  15.         perror("port error \n");  
  16.         _exit(1);  
  17.     }  
  18.   
  19.     sockfd = socket(AF_INET, SOCK_DGRAM, 0);  
  20.     if( sockfd < 0)  
  21.     {  
  22.         perror("sock fail \n");  
  23.         _exit(1);  
  24.     }  
  25.       
  26.     localaddr.sin_port = htons(atoi(argv[2]) );  
  27.     localaddr.sin_addr.s_addr = htonl(INADDR_ANY);  
  28.   
  29.     //加入哪个多播组有命令行决定  
  30.     if( inet_aton(argv[1],&mcaddr.imr_mutiaddr) < 0 )             //D类多播IP地址  
  31.     {  
  32.         perror("null mcaddr \n");  
  33.         _exit(1);  
  34.     }  
  35.   
  36.     printf("ip : %d \n",inet_ntoa(mcaddr.imr_multiaddr) );  
  37.     fflush(stdout);  
  38.   
  39.     int optval = SO_REUSEADDR ;  
  40.     if( setsockopt(sockfd, IPPROTO_TP, IP_ADD_MEMBERSHIP, &mcaddr,sizeof (stuct ip_mreq)) < 0 )   //加入多播组  
  41.     {  
  42.         perror("join mcaddr fail \n");  
  43.         _exit(1);  
  44.     }  
  45.       
  46.     if(bind(sockfd, (struct sockaddr *)&localaddr, sizeof (struct sockaddr) ) < 0 )  
  47.     {  
  48.         perror("bind fail \n");  
  49.         _exit(1);  
  50.     }  
  51.   
  52.     if( n = read(sockfd, msg,BUFLEN) == -1 )  
  53.     {  
  54.         perror("read error \n");  
  55.         _exit(1);  
  56.     }  
  57.     else  
  58.     {  
  59.         msg[n] = '0';  
  60.         printf("read time : %s \n",msg);  
  61.     }  
  62.     return 1;  
  63. }  

from: http://blog.csdn.net/kejie1235/article/details/8167584


0 0