linux网络编程(组播)
2015-06-14 11:34
399 查看
组播
1. 分组
每个D类IP地址就是一个组,组播实现原理:
接收 -- 加入一个组
发送 -- 向一个组(目标IP地址为组播地址)发送数据包
2. 组播地址(IP地址和网卡地址)
IP地址: D类地址 ,高位固定为1110,范围: 224.0.0.0-239.255.255.255
网卡地址: 前24bit固定为01-00-5e, 最后23bit是D类IP地址的后23bit直接映射下来 -- 仅仅正对于以太网
3. 接收流程
(1) 创建套接字
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
(2) 加入组
struct ip_mreq mreq;
mreq.imr_multiaddr.s_addr = inet_addr(argv[1]); // "224.10.10.1"
mreq.imr_interface.s_addr = INADDR_ANY;
ret = setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq));
(3) 绑定IP地址和端口
struct sockaddr_in addr;
bzero(&addr, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = inet_addr(ip);
// addr.sin_addr.s_addr = INADDR_ANY;
ret = bind(sockfd, (struct sockaddr *)&addr, sizeof(addr));
(4) 接收
struct sockaddr_in peer_addr;
socklen_t addrlen = sizeof(peer_addr);
ret = recvfrom(sockfd, buf, sizeof(buf), 0, (struct sockaddr *)&peer_addr, &addrlen);
(3) 关闭
close(sockfd);
4. 发送流程
(1) 创建套接字
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
(2) 发送
struct sockaddr_in muticast_addr;
bzero(&muticast_addr, sizeof(muticast_addr));
muticast_addr.sin_family = AF_INET;
muticast_addr.sin_port = htons(port);
muticast_addr.sin_addr.s_addr = inet_addr(一定填多播(224.10.10.1));
ret = sendto(sockfd, buf, len, 0, (struct sockaddr *)&broad_addr, sizeof(broad_addr));
(3) 关闭
close(sockfd);
组播(代码)
一、发送端
二、接收端
1. 分组
每个D类IP地址就是一个组,组播实现原理:
接收 -- 加入一个组
发送 -- 向一个组(目标IP地址为组播地址)发送数据包
2. 组播地址(IP地址和网卡地址)
IP地址: D类地址 ,高位固定为1110,范围: 224.0.0.0-239.255.255.255
网卡地址: 前24bit固定为01-00-5e, 最后23bit是D类IP地址的后23bit直接映射下来 -- 仅仅正对于以太网
3. 接收流程
(1) 创建套接字
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
(2) 加入组
struct ip_mreq mreq;
mreq.imr_multiaddr.s_addr = inet_addr(argv[1]); // "224.10.10.1"
mreq.imr_interface.s_addr = INADDR_ANY;
ret = setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq));
(3) 绑定IP地址和端口
struct sockaddr_in addr;
bzero(&addr, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = inet_addr(ip);
// addr.sin_addr.s_addr = INADDR_ANY;
ret = bind(sockfd, (struct sockaddr *)&addr, sizeof(addr));
(4) 接收
struct sockaddr_in peer_addr;
socklen_t addrlen = sizeof(peer_addr);
ret = recvfrom(sockfd, buf, sizeof(buf), 0, (struct sockaddr *)&peer_addr, &addrlen);
(3) 关闭
close(sockfd);
4. 发送流程
(1) 创建套接字
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
(2) 发送
struct sockaddr_in muticast_addr;
bzero(&muticast_addr, sizeof(muticast_addr));
muticast_addr.sin_family = AF_INET;
muticast_addr.sin_port = htons(port);
muticast_addr.sin_addr.s_addr = inet_addr(一定填多播(224.10.10.1));
ret = sendto(sockfd, buf, len, 0, (struct sockaddr *)&broad_addr, sizeof(broad_addr));
(3) 关闭
close(sockfd);
组播(代码)
一、发送端
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <errno.h> #include <string.h> #include <strings.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> // ./send 224.0.0.1 8888 int main(int argc, const char *argv[]) { int ret; int sockfd; char packet[1024]; struct sockaddr_in muti_addr; if (argc < 3){ fprintf(stderr, "Usage: %s <broadcast ip> <port>\n", argv[0]); exit(EXIT_FAILURE); } // 1. 创建报文套接字 sockfd = socket(AF_INET, SOCK_DGRAM, 0); if (-1 == sockfd){ perror("Fail to socket."); exit(EXIT_FAILURE); } // 2. 通过多播地址发送数据包到指定端口 bzero(&muti_addr, sizeof(muti_addr)); muti_addr.sin_family = AF_INET; muti_addr.sin_port = htons(atoi(argv[2])); muti_addr.sin_addr.s_addr = inet_addr(argv[1]); while (1){ putchar('\n'); putchar('>'); fgets(packet, sizeof(packet), stdin); packet[strlen(packet) - 1] = '\0'; ret = sendto(sockfd, packet, strlen(packet), 0, (struct sockaddr *)&muti_addr, sizeof(muti_addr)); if (-1 == ret){ perror("Fail to sendto."); break; } if (strcmp(packet, "quit") == 0){ break; } } // 3. 关闭套接字 close(sockfd); return 0; }
二、接收端
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <errno.h> #include <string.h> #include <strings.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> // ./recv 192.168.2.255 8888 int main(int argc, const char *argv[]) { int ret; int sockfd; char packet[1024]; struct sockaddr_in addr; struct ip_mreq mreq; struct sockaddr_in peer_addr; socklen_t addrlen = sizeof(peer_addr); if (argc < 3){ fprintf(stderr, "Usage: %s <broadcast ip> <port>\n", argv[0]); exit(EXIT_FAILURE); } // 1. 创建报文套接字 sockfd = socket(AF_INET, SOCK_DGRAM, 0); if (-1 == sockfd){ perror("Fail to socket."); exit(EXIT_FAILURE); } //加入组 mreq.imr_multiaddr.s_addr = inet_addr(argv[1]); mreq.imr_interface.s_addr = INADDR_ANY; ret = setsockopt(sockfd,IPPROTO_IP,IP_ADD_MEMBERSHIP,&mreq,sizeof(mreq)); if(-1 == ret){ perror("fail to setsockopt"); exit(EXIT_FAILURE); } // 2. 绑定广播地址和端口 bzero(&addr, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_port = htons(atoi(argv[2])); // broad_addr.sin_addr.s_addr = inet_addr(argv[1]); addr.sin_addr.s_addr = INADDR_ANY; ret = bind(sockfd, (struct sockaddr *)&addr, sizeof(addr)); if (-1 == ret){ perror("Fail to bind."); exit(EXIT_FAILURE); } while (1){ // 3. 接收 ret = recvfrom(sockfd, packet, sizeof(packet), 0, (struct sockaddr *)&peer_addr, &addrlen); if (-1 == ret){ perror("Fail to recvfrom."); break; } packet[ret] = '\0'; printf("---------------------------------------\n"); printf("ip : %s\n", inet_ntoa(peer_addr.sin_addr)); printf("port : %d\n", ntohs(peer_addr.sin_port)); printf("recv(%d) : %s\n", ret, packet); printf("---------------------------------------\n"); if (strcmp(packet, "quit") == 0){ break; } } // 4. 关闭套接字 close(sockfd); return 0; }
相关文章推荐
- Android弱网测试中关于网络检测的一些借鉴方法
- linux 网络编程(广播的编程)
- linux网络编程(如何编写一个UDP通信程序)
- windows 8 设置hyper-v网络设置
- 一起学习CC3200系列教程之2个TCP_非阻塞及阻塞设置
- 计算机网络--物理层 的一点总结
- ARM硬件平台上基于UCOS移植Lwip网络协议栈
- ARM硬件平台上基于UCOS移植Lwip网络协议栈
- ARM硬件平台上基于UCOS移植Lwip网络协议栈 分类: 嵌入式开发学习 2015-06-14 10:33 55人阅读 评论(1) 收藏
- unity开发:Qt C++与unity之间TCP网络通信
- 网络传输
- BZOJ 3391: [Usaco2004 Dec]Tree Cutting网络破坏( dfs )
- TCP/IP详解_网际协议IP(二)_IP数据报格式
- TCP 报文
- 关于DNS DHCP FTP TFTP HTTP WEB
- TCP/IP 11种状态变迁
- 使用TCP协议写一个可以上传文件的服务器和客户端
- Linux网络设备驱动-- skb
- HDU--杭电--2732//POJ--2711--Leapin' Lizards--网络流
- Wireshark过滤规则之:IP数据包过滤