linux下 基于libmad的socket多用户mp3音频在线播放服务器

本文介绍了一个使用libmad库和socket在Linux下构建的多用户MP3音频流媒体服务器。服务器通过多线程与多个客户端通信,提供音频列表供选择,并实现实时解码播放。文章详细讲解了如何获取音频列表,并展示了服务器和客户端代码。然而,目前该系统在不同计算机间的TCP传输中存在丢包问题,且服务器需一次性发送完整音频文件,否则可能导致解码失败。
摘要由CSDN通过智能技术生成

在众多大神的帮助下,这个在线播放流媒体服务器终于完成啦。。。。
这个mp3流媒体服务器设计的思路是,服务器程序server用多线程实现和多个客户端的通信(这是必然的),然后发送给客户端当前的音频列表公客户端选择,之后根据k客户端的选择给多个客户端传输相应mp3文件的数据,同时,客户端进行实时地音频解码并播放。
关于libmad开源mp3音频解码库的使用,见上一篇博客吧。。。。
在服务器程序这一端,首先我们要获取当前的音频列表。这里我们用到了glob函数来获取文件的列表。glob() 函数返回匹配指定模式的文件名或目录。 该函数返回一个包含有匹配文件 / 目录的数组。如果出错返回 false。
下面我们在终端中输入 man glob 来看一下glob函数的手册:
int glob(const char *pattern // 文件路径, int flags // 匹配模式,
int (*errfunc) (const char *epath, int eerrno) // 查看错误信息,不需要 则为NULL,
glob_t *pglob // 注意是glob变量的指针);
void globfree(glob_t *pglob);
其中,glob_t 变量是一个结构体,在手册中我们即可看到:
glob变量:
// ** 表示列表 (二维数组,可以用for循环查看其元素)
typedef struct {
size_t gl_pathc; /* Count of paths matched so far */ //迄今为止匹配的路径个数
char *gl_pathv; / List of matched pathnames. */ // 匹配的路径列表
size_t gl_offs; /* Slots to reserve in gl_pathv. */
} glob_t;
而使用for循环即可看到文件列表,之后globfree释放空间。
下面是一个简单的例程,可以实现固定路径下mp3文件的列表显示:

 #include <stdio.h>
 #include <glob.h>

 int main(int argc, const char *argv[])
 {
     glob_t buf;
      int i;
     glob("/home/gaoyuzhe/music/*.mp3",GLOB_NOSORT, NULL, &buf);                                                                                 

    for(i=0; i < buf.gl_pathc; i++)
    {
         printf("buf.gl_pathv[%d]= %s \n", i, (buf.gl_pathv[i]));
    } 
    globfree(&buf);
     return 0;
}

接下来我们进入正题,首先贴出代码:
服务器 server.c


#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <pthread.h>
#include <glob.h>

#include <sys/stat.h>   
#include <fcntl.h>

#define MAXSIZE 512
#define BUF_SIZE 4000000 //缓冲区的大小,也就是一次性传输数据的字节数
#define PORT 1234

/*函数声明*/
void *start_routine(void* arg);
void process_client(int connectfd, struct sockaddr_in client_addr);

    struct sockaddr_in server_addr,client_addr;
    int listenfd = 0,connectfd = 0;
    pthread_t thread;
    struct ARG{
    int connfd;//文件连接描述符
    struct sockaddr_in client;//客户端地址信息
    };      
    struct ARG *arg;

    struct MUSIC_PLAY{
    char content[BUF_SIZE];
        int size;
    };

int main()
{

   //创建套接字
    socklen_t cli_addr_size;
    listenfd =  socket(PF_INET, SOCK_STREAM,0);
    if(listenfd &
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值