Linux 网络通信之组播
2015-12-07 14:40
585 查看
组播可以看成是单播和广播的折中。当发送组播数据包时,只有加入指定多播组的主机数据链路层才会处理,其他主机在数据链路层会直接丢掉收到的数据包。即我们可以通过组播的方式和指定的若干台主机通信。
D类地址:范围从224.0.0.1到239.255.255.254.此类地址又称为组播地址。每个组播地址代表一个多播组。
组播包的发送和接收通过UDP套接字实现。
组播包发送流程如下:
(1)创建UDP套接字;socket(AF_INET, SOCK_DGRAM, 0)
(2)指定目标地址和端口;struct sockaddr_in
(3)发送数据包;sendto( )
send.c
组播接收流程如下:
(1)创建UDP套接字;socket(AF_INET, SOCK_DGRAM, 0)
(2)加入多播组;setsockopt( )
(3)填充组播地址信息(组播IP地址和端口);struct sockaddr_in
(4)接收数据包;recvfrom( )
多播结构体:
recv.c
D类地址:范围从224.0.0.1到239.255.255.254.此类地址又称为组播地址。每个组播地址代表一个多播组。
组播包的发送和接收通过UDP套接字实现。
组播包发送流程如下:
(1)创建UDP套接字;socket(AF_INET, SOCK_DGRAM, 0)
(2)指定目标地址和端口;struct sockaddr_in
(3)发送数据包;sendto( )
send.c
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <arpa/inet.h> #include <netinet/in.h> #include <string.h> #define err_log(log) do{perror(log); exit(1);}while(0) #define N 128 int main(int argc, const char *argv[]) { int sockfd; struct sockaddr_in groupcastaddr; char buf = {0}; if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { err_log("fail to socket"); } groupcastaddr.sin_family = AF_INET; groupcastaddr.sin_addr.s_addr = inet_addr("225.0.0.3"); groupcastaddr.sin_port = htons(10000); while(1) { printf("Input > "); fgets(buf, N, stdin); if(sendto(sockfd,buf, N, 0, (struct sockaddr *)&groupcastaddr, sizeof(groupcastaddr)) < 0) { err_log("fail to sendto"); } } return 0; }
组播接收流程如下:
(1)创建UDP套接字;socket(AF_INET, SOCK_DGRAM, 0)
(2)加入多播组;setsockopt( )
(3)填充组播地址信息(组播IP地址和端口);struct sockaddr_in
(4)接收数据包;recvfrom( )
多播结构体:
struct ip_mreq { /* IP multicast address of group. */ 组播的ip地址 struct in_addr imr_multiaddr; /* Local IP address of interface. */ 本机的ip地址 struct in_addr imr_interface; }; mreq.imr_multiaddr.s_addr = inet_addr(“224.10.10.1”); //组播地址 mreq.imr_interface.s_addr = htonl(INADDR_ANY); //INADDR_ANY 0 地址 ,任意的主机地址 setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq));
recv.c
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <arpa/inet.h> #include <netinet/in.h> #include <string.h> #define err_log(log) do{perror(log); exit(1);}while(0) #define N 128 int main(int argc, const char *argv[]) { int sockfd; char buf ; struct sockaddr_in groupcastaddr, srcaddr; struct ip_mreq mreq; if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { err_log("fail to socket"); } /*为套接字绑定组播地址和端口*/ groupcastaddr.sin_family = AF_INET; groupcastaddr.sin_addr.s_addr = inet_addr("225.0.0.3"); groupcastaddr.sin_port = htons(10000); /*加入多播组,允许数据链路层处理指定组播包*/ mreq.imr_multiaddr.s_addr = inet_addr("225.0.0.3"); mreq.imr_interface.s_addr = htonl(INADDR_ANY); if(setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP,&mreq, sizeof(mreq)) < 0) { err_log("fail to setsockopt"); } int on = 1; if(setsockopt(sockfd,SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) { err_log("fail to setsockopt"); } if(bind(sockfd, (struct sockaddr*)&groupcastaddr, sizeof(groupcastaddr)) < 0) { err_log("fail to bind"); } socklen_t addrlen = sizeof(struct sockaddr); while(1) { if(recvfrom(sockfd,buf, N, 0, (struct sockaddr *)&srcaddr, &addrlen) < 0) { err_log("fail to sendto"); } printf("buf:%s ---> %s %d\n", buf, inet_ntoa(srcaddr.sin_addr), ntohs(srcaddr.sin_port)); } return 0; }
相关文章推荐
- 说说IO(八)- 三分天下
- 文章5:http协议中content-length 以及chunked编码分析
- httpd-2.4.9编译安装与配置(CGI、虚拟主机、https、deflate压缩)
- Android网络编程七:OkHttp
- 说说IO(二)- IO模型
- Effective OkHttp
- Android中的JSON详细总结 本文转自:http://shazhuzhu1.iteye.com/blog/974758
- Linux 网络通信之广播
- 【google M】android 网络服务状态运行机制(语音、数据注册状态;运营商信息PLMN,SPN;radio技术;信号强度)
- 获取网络上歌曲下载链接
- Linux网络编程一步一步学 - 目录(汇总)zhuan
- Linux网络编程简单示例
- linux 网络编程---->多路复用:select实例!
- Linux网络编程之socket文件传输示例
- linux 网络编程-基础篇
- Linux环境下网络编程杂谈
- Linux网络编程--多线程实现echo服务器与客户端“一对多”功能,网络编程的“Hello World!” - 壮壮熊
- Linux 网络编程 简单实例
- linux网络编程实现投票功能
- HttpURLConnection连接网页和获取数据的使用实例