`
peizhiinfo
  • 浏览: 1428737 次
文章分类
社区版块
存档分类
最新评论

基于Linux的多播编程

 
阅读更多

基于Linux的多播编程

一.单播,广播和多播

1.单播用于两个主机之间的端对端通信,广播用于一个主机对整个局域网上所有主机上的数据通信。单播和广播是两个极端,要么对一个主机进行通信,要么对整个局域网上的主机进行通信。实际情况下,经常需要对一组特定的主机进行通信,而不是整个局域网上的所有主机,这就是多播的用途。

2.多播的概念:

1>多播,也称为“组播”,将局域网中同一业务类型主机进行了逻辑上的分组,进行数据收发的时候其数据仅仅在同一分组中进行,其他的主机没有加入此分组不能收发对应的数据。

2>在广域网上广播的时候,其中的交换机和路由器指向需要获取数据的主机复制并转发数据。主机可以向路由器请求加入或退出某个组,网络中的路由器和交换机有选择地复制并传输数据,将数据仅仅传输给组内的主机。

3.多播的优点和缺点

1>优点:

Ø 具有同种业务的主机加入同一数据流,共享同一通道,节省了带宽和服务器的优点,具有广播的优点而又没有广播所需要的带宽。

Ø 服务器的总带宽不受客户端带宽的限制。由于组播协议由接收者的需求来确定是否进行数据流的转发,所以服务器端的带宽是常量,与客户端的数量无关。

Ø 与单播一样,多播是允许在广域网即Internet上进行传输的,而广播仅仅在同一局域网上才能进行。

2>组播的缺点:

Ø 多播与单播相比没有纠错机制,当发生错误的时候难以弥补,但是可以在应用层来实现此种功能

Ø 多播的网络支持存在缺陷,需要路由器及网络协议栈的支持。

4.目前多播的应用主要有网上视频,网上会议等

5.多播地址:

1>多播的地址是特定的,D类地址用于多播。D类IP地址就是多播IP地址,即224.0.0.0到239.255.255.255之间的IP地址,并被划分为局部连续多播地址,预留多播地址和管理权限多播地址3类:

Ø 局部多播地址:在224.0.0.0~224.0.0.251之间,这是路由协议和其他用途保留的地址,路由器并不转发属于此范围的IP包。(即此类范围的多播IP地址只能在局域网内使用)

Ø 预留多播地址:在224.0.1.0~238.255.255.255之间,可用于全球范围或网络协议

Ø 管理权限多播地址:在239.0.0.0~239.255.255.255之间,可供组织内部使用,类似于私有IP地址,不能用于Internet,可限制多播范围。

6.IPv4多播地址到以太网地址的映射方法:

1>IPv4的D类地址(从224.0.0.0到239.255.255.255)是IPv4多播地址;D类地址的低序28位构成多播组ID(group ID),整个32位地址则称为组地址(group address)。

2>IPv4地址的映射,以太网地址的高24位总是01:00:5e下一位总是0,底序23位拷贝自多播组ID的底序23位。这样就组成了多播地址的以太网地址。

二.多播编程

1>建立一个socket;

2>设置多播的参数,例如超时时间TTL,本地回环许可LOOP等

3>加入多播组

4>发送和接收数据

5>从多播组离开

2.多播程序设计使用setsockopt()函数和getsockopt()函数来实现,组播的选项是IP层的。

3.setsockopt()的选项

1>IP_MULTICAST_TTL:设置多播组数据的TTL值(路由跳数),每跨过一个路由器,TTL值减一.范围为0~255之间的任何值。

int ttl;

setsockopt(sock_fd,IPPROTO_IP,IP_MULTICAST_TTL,&ttl,sizeof(ttl));

2>IP_MULTICAST_LOOP:默认情况下,当本机发送组播数据到某个网络接口时,在IP层,数据会回送公道本地的回环接口,选项IP_MULTICAST_LOOP用于控制数据是否回送到本地的回环接口。

int loop;

setsockopt(sock_fd,IPPROTO_IP,IP_MULTICAST_LOOP,&loop,sizeof(loop));

参数loop设置为0表示禁止回送,设置为1允许回送。

3>IP_ADD_MEMBERSHIP: 该选项通过对一个结构struct ip_mreq类型的变量进行控制而加入一个多播组。

Ø structip_mreq

struct ip_mreq

{

structin_addr imr_multiaddr;/*加入的多播组IP地址*/

struct in_addr imr_interface;/*加入的网络接口IP地址*/

};

Ø 选项IP_ADD_MEMBESHIP选项用于加入某个多播组,之后就可以向这个多播组发送数据或者从多播组接收数据。此选项的值为mreq结构,成员imr_multiaddr是需要加入的多播组IP地址,成员imr_interface是本机需要加入多播组的网络接口IP地址。

structip_mreq mreq;

setsockopt(sock_fd,IPPROTO_IP,IP_ADD_MEMBERSHIP,&mreq,sizeof(mreq));

Ø 使用IP_ADD_MEMBERSHIP选项每次只能加入一个网络接口的IP地址到多播组,但并不是一个多播组仅允许一个主机IP地址加入,可以多次调用IP_ADD_MEMBERSHIP选项来实现多个IP地址加入同一个多播组,或者同一个IP地址加入多个多播组。当imr_interface为INADDR_ANY时,选择的本地默认网口。

4>IP_DROP_MEMBERSHIP:该选项用于从一个多播组中退出。

structip_mreq mreq;

setsockopt(sock_fd,IPPROTP_IP,IP_DROP_MEMBERSHIP,&merq,sizeof(sreq));

三实例:

情景:

Ø 服务器端每隔2秒向目的端口号为5000和目的多播地址为224.0.0.255发送数据welcome you to multicast socket programme。

Ø 客户端从多播地址为224.0.0.255和端口号5000处接收5次多播数据。

1.服务器端程序


1 #include<stdio.h>
2 #include<string.h>
3 #include<stdlib.h>
4 #include<unistd.h>
5 #include<sys/socket.h>
6 #include<sys/types.h>
7 #include<arpa/inet.h>
8 #include<netinet/in.h>
9
10 #define SERV_PORT 5350
11 #define MCAST_PORT 5350
12 #define MCAST_ADDR "224.0.0.251"
13 #define MCAST_INTERVAL 2
14
15 int main(int argc,char **argv)
16 {
17 int sock_fd;
18 struct sockaddr_in mcast_addr,addr_serv,addr_client;
19 char send_buf[]="tigerjibo";
20 char recv_buf[1024];
21 int serv_len,mcast_len;
22 int send_num;
23 int recv_num;
24 int err;
25 struct ip_mreq mreq;
26 sock_fd = socket(AF_INET,SOCK_DGRAM,0);/*建立套接子*/
27 if(sock_fd < 0){
28 perror("socket()");
29 exit(1);
30 } else {
31 printf("socket sucefull!\n");
32 }
33 /*服务器端地址*/
34 memset(&addr_serv,0,sizeof(struct sockaddr_in));
35 addr_serv.sin_family = AF_INET;
36 addr_serv.sin_addr.s_addr = inet_addr("192.168.1.11");
37 addr_serv.sin_port = htons(SERV_PORT);
38 serv_len = sizeof(struct sockaddr_in);
39 //初始化多播地址
40 memset(&mcast_addr,0,sizeof(mcast_addr));
41 mcast_addr.sin_family = AF_INET;
42 mcast_addr.sin_addr.s_addr = inet_addr(MCAST_ADDR);
43 mcast_addr.sin_port = htons(MCAST_PORT);
44
45 if(bind(sock_fd,(struct sockaddr*)&addr_serv,serv_len)<0){

46 perror("bind");
47 exit(1);
48 } else {
49 printf("bind sucess\n");
50 }
51 while(1){
52 printf("begin send:\n");
53 send_num = sendto(sock_fd,send_buf,sizeof(send_buf),0,(struct sockaddr *)&mcast_addr,sizeof(mcast_addr));
54 if( send_num < 0){
55 perror("sendto()");
56 exit(1);
57 } else{
58 printf("send sucessful\n");
59 }
60 sleep(MCAST_INTERVAL);
61 }
62 close(sock_fd);
63 return 0;
64 }
64,1 底端

2.客户端程序



1 #include<stdio.h>
2 #include<string.h>
3 #include<stdlib.h>
4 #include<errno.h>
5
6 #include<sys/socket.h>
7 #include<sys/types.h>
8 #include<arpa/inet.h>
9 #include<netinet/in.h>
10 #include<unistd.h>
11 #define LOCAL_PORT 5350
12 #define MCAST_ADDR "224.0.0.251"
13 #define MCAST_INTERVAL 5
14 #define LOCAL_ADDR "192.168.1.11"
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33 int main()
34 {
35 int sock_fd;
36 struct sockaddr_in local_addr;
37 int err = -1;
38 int loop = 1;
39 sock_fd = socket(AF_INET,SOCK_DGRAM,0);/*建立套接字*/
40 if(sock_fd < 0){
41 perror("socket()");
42 exit(1);
43 } else {
44 printf("socket() sucessful\n");

45 }

46 memset(&local_addr,0,sizeof(local_addr));
47 local_addr.sin_family = AF_INET;
48 local_addr.sin_addr.s_addr = htonl(INADDR_ANY);//inet_addr(LOCAL_ADDR);htonl(INADDR_ANY);固定为local_addr则接受不到
49 local_addr.sin_port = htons(LOCAL_PORT);
50 err = bind(sock_fd,(struct sockaddr *)&local_addr,sizeof(local_addr));
51 if(err < 0){
52 perror("bind");
53 exit(1);
54 } else {
55 printf("bind sucessful\n");
56 }
57 loop = 1;
58 err = setsockopt(sock_fd,IPPROTO_IP,IP_MULTICAST_LOOP,&loop,sizeof(loop));
59 if(err < 0){
60 perror("setsocket():IP MULTICAST_LOOP");
61 exit(1);
62 } else {
63 printf("IP_MULTICAST_LOOP SUCESSFUL\n");
64 }
65
66 struct ip_mreq mreq;
67 mreq.imr_multiaddr.s_addr = inet_addr(MCAST_ADDR);
68 mreq.imr_interface.s_addr = inet_addr(LOCAL_ADDR);
69 err = setsockopt(sock_fd,IPPROTO_IP,IP_ADD_MEMBERSHIP,&mreq,sizeof(mreq));
70 if(err < 0){
71 printf("%s setsockopt():IP ADD MEMBURSHIP\n",strerror(errno));
72 exit(1);
73 } else {
74 printf("setsockopt() IP ADD MEMBURSHIP sucessful\n");
75 }
76 int times = 0;
77 int addr_len = 0;
78 char buff[1000];
79 int recv_num =0;
80 for(times = 0;times < 5;times++){
81 addr_len = sizeof(local_addr);
82 memset(buff,0,sizeof(buff));
83 recv_num = recvfrom(sock_fd,buff,sizeof(buff),0,(struct sockaddr*)&local_addr,&addr_len);
84 if(recv_num < 0){

85 perror("recvfrom()");
86 exit(1);
87 } else {
88 printf("Recv %dst message from server :%s\n",times,buff);
89 sleep(MCAST_INTERVAL);
90 }
91 }
92 err = setsockopt(sock_fd,IPPROTO_IP,IP_DROP_MEMBERSHIP,&mreq,sizeof(mreq));
93 close(sock_fd);
94 return 0;
95 }

分享到:
评论

相关推荐

    Linux下基于socket的网络编程(包含多线程和Select机制)

    本程序是Linux下基于socket套接字完成的简单网络编程程序,可以接收Tcp、Udp单播、Udp组播消息,并且加入了Select机制和多线程编程,比较简单,适合初学者使用。

    基于linux的电子相册

    这个项目使用arm开发板,运用了linux系统的文件读取,写入、arm的LED屏幕的图片显示和触摸屏控制等功能。 进入系统后程序会自动读取储存图片的文件夹里面的图片文件,之后会显示一个主界面,点击主界面中的类似...

    基于RTSP的linux环境编程的客户端实现

    RTSP(Real Time Streaming Protocol),参考标准为RFC2326,实时流传输协议,是TCP/IP协议体系中的一个 应用层协议提供播放、暂停、后退、前进等操作。 主要用来控制具有实时特性的数据的发送,但其本身并不用于...

    UDP.rar_C语言udp组播_linux UDP_udp linux _udp组播c语言

    基于linux网络C语言编程-UDP组播

    Linux媒体音乐播放器项目设计编程(6818)

    Linux项目设计:斗罗大陆宣传系统、基于Linux系统的媒体播放器、可播放音视频图片(基于gec6818项目设计) 项目功能展示: 一、开机显示登入界面,可密码管理员登入,也可以免密码普通用户登入 二、登入后显示桌面,...

    两套,linux的录音播放程序代码基于alsa

    共有两套代码,有注释,有c基础都能看得懂 如果编译时出现缺少的警告alsa/asoundlib.h,则是缺少一个库,用upt-get install bliasound2-dev 安装库就可以编译了 此外,编译格式 例如 gcc playback.c -o playback -...

    基于UDP多播聊天室

    liunx 下的基于udp的聊天室 小项目

    给予Linux下的MP3播放器

    基于Linux下的MP3播放器,该程序是用C语言编写,用到的知识点包括多进程,信号编程等等

    linux网路编程 中文 23M 版

    第2 章Linux编程环境....................................................................................................14 2.1 Linux环境下的编辑器................................................. 14 ...

    linux系统下基于TCP协议流媒体的简单实现(带实验报告)

    linux系统下利用tcp协议传输视频流并用MPlayer播放器播放,内带实验报告,和MPlayer播放器的所有安装包及安装方法。

    MPP.tar.gz_linux下的·mp3_播放Mp3_链表mp3

    基于Linux系统,对本地歌曲的识别、读取、存储、更新等处理生成MP3歌曲链表,并能够创建不同的播放链表实现分类存储。终端输入命令使用多进程编程方式实现对所选的MP3文件播放功能播放功能,播放器主要实现了定时...

    2022年山东科技大学Linux大作业【源码、实验报告】

    个人linux实验作业【源码、实验报告】,成绩优,仅供参考学习,切勿抄袭。以下功能全部都实现: 系统分为服务器和客户端。 服务器端实现对音乐...2.系统基于Linux系统实现,编程语言采用C语言 3.网络传输协议采用TCP

    UNIX网络编程卷2进程间通信

    讨论的新主题包括: POSIX Single UNIX Specification Version 3 IPv6 APIs(包括更新了的对IPv6/IPv4互操作性的指南) 新的SCTP传输协议 基于IPsec的密钥管理套接字 FreeBSD 4.8/5.1、Red Hat Linux 9.x、...

    基于QT平台的手持媒体播放器项目实战

    第二讲:Linux下QT开发环境搭建1:VMWare安装及使用、Linux安装及使用 第三讲:Linux下QT开发环境搭建2:QT X11编译、安装、使用 第四讲:Linux下QT开发环境搭建3:QTEmbedded交叉编译 第五讲:Linux下C++...

    Linux 平台基于 Qt + MYSQL 的聊天程序.zip

    它支持多种操作系统,包括但不限于Windows、macOS、Linux、Android和iOS。通过Qt,开发者可以使用同一套源代码,在不同平台上编译并生成原生外观与体验的应用程序,极大地提高了开发效率和产品一致性。 图形用户...

    PHP网络编程技术与实践 源码

    15.4 基于Socket编写的程序 15.5 本章小结 第16章 视频音频播放模块 16.1 播放器的基础知识 16.1.1 Windows Media Player 16.1.2 RealPlayer 16.2 播放列表的生成 16.3 视频音频播放的应用示例 16.3.1 自己风格的...

    FFMPEG_Examples_On_Windows:FFmpeg的开发是基于Linux操作系统,但是可以在大多数操作系统中编译和使用

    英语可以直接去官网简介FFmpeg的是一个集录制,转换,音/视频编码解码功能为一体的完整的开源解决方案.FFmpeg的开发是基于Linux的操作系统,但是可以FFmpeg工具ffmpeg:快速formp mpeg音频视频转换器转换多媒体文件...

    基于FrameBuffer的电子相册

    1.在Linux环境下,用C语言高级编程中的多进程、进程间通讯、信号、链表、文件的读写等实现电子相册中音乐的播放、照片的自动播放、手动播放以及图片的浏览等功能。 2. 电子相册功能:进行9宫格预览,上一页,下一页...

    基于C++开发的嵌入式QT车载影音系统源码+项目详细说明.zip

    本次项目是基于Qt环境进行开发设计一个基于嵌入式QT的车载影音系统应用,通过交叉编译Qt程序,并在GEC6818开发板上运行,主要通过Qt基础控件、多窗体、样式表、Qt多进程、Http请求、API接口调用、JSON数据解析、...

    《Android高级编程》

    更多关于安卓软件系统详情-安卓风 目录: 第1章 Android简介 1.1 一些背景信息 1.1.1 不远的过去 1.1.2 未来的前景 1.2 对Android的误解 1.3 开放的移动开发平台 1.4 自带的Android应用程序 1.5 Android SDK...

Global site tag (gtag.js) - Google Analytics