├── README.md ├── broadc-udpclient.c ├── mcastclient.c ├── mcastserver.c ├── simple_udpclient.c └── simple_udpserver.c /README.md: -------------------------------------------------------------------------------- 1 | # mcast 2 | UDP connection and UDP broadcast, multicast to achieve the server program 3 | 4 | UDP 广播,多播,组播的简单实现。 5 | -------------------------------------------------------------------------------- /broadc-udpclient.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | /** 11 | *filename:broadc-udpclient.c 12 | *purpose:基本编程步骤, 演示了UDP编程的广播客户端编程步骤 13 | */ 14 | 15 | int main(int argc, char *argv[]) 16 | { 17 | struct sockaddr_in servaddr; 18 | int sockfd; 19 | int addr_len; 20 | int len; 21 | char buff[128]; 22 | int yes; 23 | 24 | /*创建socket,关键在于在SOCK_DGRAM*/ 25 | if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1){ 26 | perror("socket"); 27 | exit(errno); 28 | }else 29 | printf("created socket.\n\r"); 30 | 31 | /*设置通讯方式为广播,即本程序发送的一个消息, 网络上所有主机均可以收到*/ 32 | yes = 1; 33 | setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &yes, sizeof(yes)); 34 | /*唯一变化就是这一点*/ 35 | 36 | /*设置对方的地址和端口信息*/ 37 | servaddr.sin_family = AF_INET; 38 | if(argv[2]) 39 | servaddr.sin_port = htons(atoi(argv[2])); 40 | else 41 | servaddr.sin_port = htons(7838); 42 | 43 | if(argv[1]) 44 | servaddr.sin_addr.s_addr = inet_addr(argv[1]); 45 | else{ 46 | printf("消息必须有一个接受者!\n"); 47 | exit(0); 48 | } 49 | 50 | /*发送UDP消息*/ 51 | addr_len = sizeof(servaddr); 52 | strcpy(buff, "hello , i'm here"); 53 | len = sendto(sockfd, buff, strlen(buff), 0, (struct sockaddr*)&servaddr, addr_len); 54 | if(len < 0){ 55 | printf ("\n\rsend error.\n\r"); 56 | return 3; 57 | } 58 | 59 | printf ("send success.\n"); 60 | 61 | return 0; 62 | } 63 | 64 | -------------------------------------------------------------------------------- /mcastclient.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #define BUFLEN 255 11 | 12 | /** 13 | *filename:mcastclient.c 14 | *purpose:演示组播编程的接本步骤,其实就是一个基本的UDP客户端(组播客户端) 15 | */ 16 | int main(int argc, char *argv[]) 17 | { 18 | struct sockaddr_in servaddr, cliaddr; 19 | int sockfd; 20 | char recmsg[BUFLEN + 1]; 21 | unsigned int socklen; 22 | 23 | /*创建socket用于UDP通讯*/ 24 | if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1){ 25 | printf ("socket creating error\n"); 26 | exit(1); 27 | } 28 | socklen = sizeof(struct sockaddr_in); 29 | 30 | /*设置对方的端口号和IP信息*/ 31 | memset(&servaddr, 0, socklen); 32 | servaddr.sin_family = AF_INET; 33 | if(argv[2]) 34 | servaddr.sin_port = htons(atoi(argv[2])); 35 | else 36 | servaddr.sin_port = htons(7838); 37 | 38 | if(argv[1]){/*注意这里设置对方地址是指组播地址, 而不是对方的实际IP地址*/ 39 | if(inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0){ 40 | printf ("wrong group address!\n"); 41 | exit(0); 42 | } 43 | }else{ 44 | printf("no group address!\n"); 45 | exit(0); 46 | } 47 | 48 | /*设置自己的端口和IP信息*/ 49 | memset(&cliaddr, 0, socklen); 50 | cliaddr.sin_family = AF_INET; 51 | if(argv[4]) 52 | cliaddr.sin_port = htons(atoi(argv[4])); 53 | else 54 | cliaddr.sin_port = htons(23456); 55 | 56 | if(argv[3]){ 57 | if(inet_pton(AF_INET, argv[3], &cliaddr.sin_addr) <= 0){ 58 | printf ("self ip address error!\n"); 59 | exit(0); 60 | } 61 | }else 62 | cliaddr.sin_addr.s_addr = INADDR_ANY; 63 | 64 | /*绑定自己的端口和IP地址到socket上*/ 65 | if(bind(sockfd, (struct sockaddr*)&cliaddr, sizeof(struct sockaddr_in)) == -1){ 66 | printf("bind error!\n"); 67 | exit(0); 68 | } 69 | 70 | /*循环接受用户输入的信息发送组播消息*/ 71 | for( ; ; ){ 72 | /*接受用户输入*/ 73 | bzero(recmsg, BUFLEN + 1); 74 | if(fgets(recmsg, BUFLEN, stdin) == (char*)EOF) 75 | exit(0); 76 | /*发送消息*/ 77 | if(sendto(sockfd, recmsg, strlen(recmsg), 0, (struct sockaddr*)&servaddr, 78 | sizeof(struct sockaddr_in)) < 0){ 79 | printf("sendto error!\n"); 80 | exit(3); 81 | } 82 | printf("'%s'send ok\n", recmsg); 83 | } 84 | return 0; 85 | } 86 | -------------------------------------------------------------------------------- /mcastserver.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | /** 11 | *filename:mcastserver.c 12 | *演示组播编程的基本步骤, 组播服务端, 关键在于加入组 13 | */ 14 | #define BUFLEN 255 15 | 16 | int main(int argc, char *argv[]) 17 | { 18 | struct sockaddr_in servaddr; 19 | struct in_addr ia; 20 | int sockfd; 21 | char recmsg[BUFLEN + 1]; 22 | unsigned int socklen, n; 23 | struct hostent *group; 24 | struct ip_mreq mreq; 25 | 26 | /*创建socket用于UDP通讯*/ 27 | sockfd = socket(AF_INET, SOCK_DGRAM, 0); 28 | if(sockfd < 0){ 29 | printf("socket creating err in udptalk\n"); 30 | exit(1); 31 | } 32 | 33 | /*设置要加入组播的地址*/ 34 | bzero(&mreq, sizeof(struct ip_mreq)); 35 | if(argv[1]){ 36 | if((group = gethostbyname(argv[1])) == (struct hostent*)0){ 37 | perror("gethostbyname"); 38 | exit(errno); 39 | } 40 | }else{ 41 | printf ("you should give me a group address, 224.0.0.0-239.255.255.255\n"); 42 | exit(errno); 43 | } 44 | 45 | bcopy((void*)group->h_addr, (void*)&ia, group->h_length); 46 | /*设置组地址*/ 47 | bcopy(&ia, &mreq.imr_multiaddr.s_addr, sizeof(struct in_addr)); 48 | 49 | /*设置发送组播消息的源主机的地址信息*/ 50 | mreq.imr_interface.s_addr = htonl(INADDR_ANY); 51 | 52 | /*把本机加入组播地址, 即本机卡作为组播成员, 只要加入组才能收到组播消息*/ 53 | if(setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, 54 | sizeof(struct ip_mreq)) == -1){ 55 | perror("setsockopt"); 56 | exit(-1); 57 | } 58 | 59 | socklen = sizeof(struct sockaddr_in); 60 | memset(&servaddr, 0, socklen); 61 | servaddr.sin_family = AF_INET; 62 | if(argv[2]) 63 | servaddr.sin_port = htons(atoi(argv[2])); 64 | else 65 | servaddr.sin_port = htons(7838); 66 | 67 | if(argv[1]){ 68 | if(inet_pton(AF_INET, argv[1], &servaddr.sin_addr) < 0){ 69 | printf("Wrong dest IP address!\n"); 70 | exit(0); 71 | } 72 | }else{ 73 | printf("no group address given, 224.0.0.0-239.255.255.255\n"); 74 | exit(errno); 75 | } 76 | 77 | /*绑定自己的端口和IP信息到socket上*/ 78 | if(bind(sockfd, (struct sockaddr*)&servaddr, sizeof(struct sockaddr_in)) == -1){ 79 | printf("Bind error\n"); 80 | exit(0); 81 | } 82 | 83 | /*循环j接收网络上来的组播消息*/ 84 | for( ; ; ){ 85 | bzero(recmsg, BUFLEN + 1); 86 | n = recvfrom(sockfd, recmsg, BUFLEN, 0,(struct sockaddr*)&servaddr, &socklen); 87 | if(n < 0){ 88 | printf("recvfrom err in udptalk!\n"); 89 | exit(4); 90 | }else{ 91 | /*成功接收到数据报*/ 92 | recmsg[n] = 0; 93 | printf ("peer:%s",recmsg); 94 | } 95 | } 96 | return 0; 97 | } 98 | 99 | -------------------------------------------------------------------------------- /simple_udpclient.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | /** 11 | *filename:simple_udpclient.c 12 | *purpose:基本编程,演示UDP编程的客户端编程步骤 13 | */ 14 | 15 | int main(int argc, char *argv[]) 16 | { 17 | struct sockaddr_in servaddr; 18 | int sockfd; 19 | int addr_len; 20 | int len; 21 | char buff[128]; 22 | 23 | /*创建socket,关键在于在SOCK_DGRAM*/ 24 | if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1){ 25 | perror("socket"); 26 | exit(errno); 27 | }else 28 | printf("created socket.\n\r"); 29 | 30 | /*设置对方的地址和端口信息*/ 31 | servaddr.sin_family = AF_INET; 32 | if(argv[2]) 33 | servaddr.sin_port = htons(atoi(argv[2])); 34 | else 35 | servaddr.sin_port = htons(7838); 36 | 37 | if(argv[1]) 38 | servaddr.sin_addr.s_addr = inet_addr(argv[1]); 39 | else{ 40 | printf("消息必须有一个接受者!\n"); 41 | exit(0); 42 | } 43 | 44 | /*发送UDP消息*/ 45 | addr_len = sizeof(servaddr); 46 | strcpy(buff, "hello , i'm here"); 47 | len = sendto(sockfd, buff, strlen(buff), 0, (struct sockaddr*)&servaddr, addr_len); 48 | if(len < 0){ 49 | printf ("\n\rsend error.\n\r"); 50 | return 3; 51 | } 52 | 53 | printf ("send success.\n"); 54 | 55 | return 0; 56 | } 57 | 58 | -------------------------------------------------------------------------------- /simple_udpserver.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | 11 | /** 12 | *filename:simple_udpserver.c 13 | *purpose:基本编程步骤说明, 演示UDP编程的服务器端编程步骤 14 | */ 15 | int main(int argc, char *argv[]) 16 | { 17 | struct sockaddr_in servaddr,cliaddr; 18 | int sockfd; 19 | socklen_t clilen; 20 | int len; 21 | char buff[128]; 22 | 23 | /*创建socket,关键在于在SOCK_DGRAM*/ 24 | if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1){ 25 | perror("socket"); 26 | exit(errno); 27 | } 28 | else 29 | printf ("create socket.\n"); 30 | 31 | memset(&servaddr, 0, sizeof(struct sockaddr_in)); 32 | /*设置地址和信息*/ 33 | servaddr.sin_family = AF_INET; 34 | if (argv[2]) 35 | servaddr.sin_port = htons(atoi(argv[2])); 36 | else 37 | servaddr.sin_port = htons(7838); 38 | if (argv[1]) 39 | servaddr.sin_addr.s_addr = inet_addr(argv[1]); 40 | else 41 | servaddr.sin_addr.s_addr = INADDR_ANY; 42 | 43 | /*绑定地址和端口信息*/ 44 | if((bind(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr))) == -1){ 45 | perror("bind"); 46 | exit(errno); 47 | }else 48 | printf("bind address to socket.\n\r"); 49 | 50 | /*循环接收数据*/ 51 | clilen = sizeof(cliaddr); 52 | for( ; ; ){ 53 | len = recvfrom(sockfd, buff, sizeof(buff), 0, (struct sockaddr*)&cliaddr, &clilen); 54 | if(len < 0){ 55 | perror("recvfrom"); 56 | exit(errno); 57 | } 58 | buff[len] = '\0'; 59 | printf ("收到来自%s:%d的消息:%s\n\r", 60 | inet_ntoa(cliaddr.sin_addr), ntohs(cliaddr.sin_port), buff); 61 | 62 | } 63 | return 0; 64 | } 65 | --------------------------------------------------------------------------------