最近学习Linux网络编程学到了广播与多播,就在这做点笔记。其中一些原理我就不介绍了,我觉得学习Linux网络编程,TCP/IP三卷还是基础,是需要好好看看。
广播的服务器端 :
#include <sys/socket.h> //#include <sys/inet.h> #include <sys/ioctl.h> #include <arpa/inet.h> #include <stdio.h> #include <time.h> #define BUFLEN 255 void getcurtime(char *curtime) { time_t tm = time(NULL); sprintf(curtime, "time : %d \n",tm); } int main(int argc, char **argv) { struct sockaddr_in peeraddr ; int sockfd; int optval = 1; char msg[BUFLEN+1]; if( argc != 3 ) { perror("can't input ADDRESS and PORT \n"); _exit(1); } sockfd = socket(AF_INET, SOCK_DGRAM, 0); //设置套接字 if( sockfd < 0 ) { perror("socket fail \n"); _exit(1); } setsockopt(sockfd, SOL_SOCKET,SO_BROADCAST,&optval, sizeof optval); //设置广播方式,SO_BROADCAST memset(&peeraddr, 0, sizeof(struct sockaddr_in) ); peeraddr.sin_family = AF_INET ; if( inet_aton(argv[1], &peeraddr.sin_addr) == 0 ) { perror("inet_aton fail \n"); _exit(1); } peeraddr.sin_port = htons(atoi(argv[2]) ); printf("-------------广播服务器启动------------\n"); while(1) { getcurtime(msg); sendto(sockfd, msg, strlen(msg), 0, (struct sockaddr *)&peeraddr, sizeof (struct sockaddr) ); //printf("sendto return %d \n",a); fflush(stdout); sleep(3); } return 1; }
下面是客户端 :
#include <sys/types.h> #include <sys/socket.h> #include <arpa/inet.h> #include <stdio.h> #define BUFLEN 255 int main(int argc, char **argv) { struct sockaddr_in localaddr; int sockfd,n; char msg[BUFLEN+1]; if(argc != 2) { perror("port error \n"); _exit(1); } sockfd = socket(AF_INET, SOCK_DGRAM, 0); if( sockfd < 0) { perror("sock fail \n"); _exit(1); } localaddr.sin_port = htons(atoi(argv[1]) ); localaddr.sin_addr.s_addr = htonl(INADDR_ANY); int optval = SO_REUSEADDR ; setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &optval,sizeof optval); if(bind(sockfd, (struct sockaddr *)&localaddr, sizeof (struct sockaddr) ) < 0 ) { perror("bind fail \n"); _exit(1); } if( n = read(sockfd, msg,BUFLEN) == -1 ) { perror("read error \n"); _exit(1); } else { msg[n] = '0'; printf("read time : %s \n",msg); } return 1; }
下面是多播,服务器端不需要太大的变动,只需要将广播工作方式去掉,发送地址指定为多播地址即可。但客户端需要加入多播组,没有加入多播组的客户端接受到数据报后就会丢弃。
#include <sys/types.h> #include <sys/socket.h> #include <arpa/inet.h> #include <stdio.h> #define BUFLEN 255 int main(int argc, char **argv) { struct sockaddr_in localaddr; int sockfd,n; char msg[BUFLEN+1]; struct ip_mreq mcaddr; //D类多播地址结构体 if(argc != 2) { perror("port error \n"); _exit(1); } sockfd = socket(AF_INET, SOCK_DGRAM, 0); if( sockfd < 0) { perror("sock fail \n"); _exit(1); } localaddr.sin_port = htons(atoi(argv[2]) ); localaddr.sin_addr.s_addr = htonl(INADDR_ANY); //加入哪个多播组有命令行决定 if( inet_aton(argv[1],&mcaddr.imr_mutiaddr) < 0 ) //D类多播IP地址 { perror("null mcaddr \n"); _exit(1); } printf("ip : %d \n",inet_ntoa(mcaddr.imr_multiaddr) ); fflush(stdout); int optval = SO_REUSEADDR ; if( setsockopt(sockfd, IPPROTO_TP, IP_ADD_MEMBERSHIP, &mcaddr,sizeof (stuct ip_mreq)) < 0 ) //加入多播组 { perror("join mcaddr fail \n"); _exit(1); } if(bind(sockfd, (struct sockaddr *)&localaddr, sizeof (struct sockaddr) ) < 0 ) { perror("bind fail \n"); _exit(1); } if( n = read(sockfd, msg,BUFLEN) == -1 ) { perror("read error \n"); _exit(1); } else { msg[n] = '0'; printf("read time : %s \n",msg); } return 1; }