基于ipv4的流媒体组播系统

功能描述:服务端发送所有可以收听的频道列表,由客户端先接收频道列表,然后进行选择收听哪一个频道,实现多个频道同时收听,要采取并发,选用多进程或者多线程,在这里,我采用的是多线程,因为创建一个线程的开销较小,线程拥有独立的堆栈和局部变量,线程是共用地址空间的,共享进程数据;创建,销毁,切换简单; 占用内存小;cup利用率高。

实现:

  • 线程池:有管理线程,工作线程,任务队列。

没有任务时,线程池中会有一定数量的空闲线程,不会被销毁。

管理线程是控制线程的创建和销毁,线程的数量不超过线程池中线程的最大容量,不少于线程池中线程的最小容量。线程池中线程是临界资源,需要互斥访问。

  • server端:媒体库和main函数

1. 需要创建套接字,服务端是主动端,bind可以省略,使能多播

2. 初始化线程池

3. 获得频道列表,将获得的频道列表发送到组播中(利用线程池,将发送频道列表的任务添加到线程池的任务队列中)

4. 将每个频道的数据(频道下的音频文件)发送到组播中(将发送频道数据的任务添加到线程池中的任务队列中)

  • 媒体库:实现功能:得到频道列表和单个频道数据

遇到的问题:不知道如何通过频道id得到单个频道的数据

创建一个内部数据类型:(解析每个频道得到一个内部结构体)

struct chn_context_st

{

struct mlib_st mlib_list;//频道列表

//包含mp3_path.gl_pathv(频道下所有音频的路径)和mp3_path.gl_pathc(频道下含有的音频个数)

glob_t mp3_path;

int mp3_index;//代表读的是第几个音频文件

int mp3_fd;//当前第mp3_index + 1个音频文件的文件描述符

int mp3_pos;//读第mp3_index + 1个音频读到的位置

}

解决:在得到频道列表的时候,使用了chn_context_st类型的指针数组,将每一个频道解析出来的chn_context_st类型的结构体的首地址存储到指针数组中。有了内部结构体,就可以通过chnid得到每个频道下音频的信息,从而可以读取每个音频的数据。

  • clinet端:main函数

1. 创建套接字,客户端是被动端,所以要bind,加入多播组。

2. 创建父子进程,父进程选择收听的频道,从组播中读取要收听的频道的数据,写入管道中

3. 子进程从管道中读取频道数据,进行进程替换,使用mplayer播放器,播放音频文件

  • 协议接口:定义频道列表和单个频道列表的数据类型(向组播中发送)

1. 协议中定义的数据类型是往组播中发送的时候需要遵循的,在组播中取到的数据也是协议中的类型,server向组播中传送频道列表和频道数据需要遵守,媒体库中获取频道列表和频道数据时不需要遵守协议中的数据类型。

2. 为了让客户端知道接收的数据是频道列表和频道数据,协议中定义了一个共用体结构。

  • 流量控制模块

采用令牌桶来进行流量控制

流量控制有两种方式:漏桶和令牌桶

漏桶适合偶尔一次的并发,漏桶是处理的速率是恒定的,若漏桶出现溢出,则丢弃。令牌桶是以一定的速率产生令牌,令牌桶存储的令牌有上限,若请求的令牌数量 > 令牌桶中可用的令牌的数量,则丢弃,适合一定程度的突发事件,

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值