minidlna源码初探(一)

本文介绍了minidlna作为DLNA解决方案的核心功能,包括UPnP协议的实践、目录管理和设备控制。从main函数出发,详细讨论了init、open_db等初始化步骤,以及socket连接、SSDP广播、设备描述和远程目录浏览的过程。通过VLC Media Player作为控制点,展示了minidlna如何响应和处理设备发现及服务请求。
摘要由CSDN通过智能技术生成

前言

minidlna是一种优秀的DLNA解决方案。本文将涉及minidlna的upnp以及目录管理的代码。minidlna的下载链接如下:

wget http://netcologne.dl.sourceforge.net/project/minidlna/minidlna/1.1.0/minidlna-1.1.0.tar.gz

控制点使用VLC Media Player,下载链接如下:

http://www.videolan.org/vlc/index.zh.html#download

关于minidlna的配置,网上已有很多介绍,在这里就不复述了。

本文中一些关于UPNP的理论问题参考了IBM的相关介绍:

UPnP协议编程实践(1)

UPnP协议编程实践(2)


正文

在minidlna,本文描述的主要内容分布在minidlna.c(主程序),inotify.c(目录管理),upnphttp.c(upnp通信),minissdp.c(ssdp设备发现相关),upnpsoap.c(soap设备控制相关)等。

照例从main函数进入,这个在~/minidlna.c下。程序首先执行了init,open_db等方法:

ret = init(argc, argv);   //这里主要分析配置文件以及命令中的选项
//......
LIST_INIT(&upnphttphead); //初始化upnphttphead
ret = open_db(NULL);  //新建sqlite3 db
//......
check_db(db, ret, &scanner_pid);

新建连接用socket:

sudp = OpenAndConfSSDPReceiveSocket();   //新建一个socket,执行setsockopt并且bind之, sudp就是返回的socket , 端口号SSDP_PORT(1900), 用于接受控制点信息
if (sudp < 0)
{
	DPRINTF(E_INFO, L_GENERAL, "Failed to open socket for receiving SSDP. Trying to use MiniSSDPd\n");
	if (SubmitServicesToMiniSSDPD(lan_addr[0].str, runtime_vars.port) < 0)
		DPRINTF(E_FATAL, L_GENERAL, "Failed to connect to MiniSSDPd. EXITING");
}
/* open socket for HTTP connections. Listen on the 1st LAN address */
shttpl = OpenAndConfHTTPSocket(runtime_vars.port);  //新建一个socket,执行setsockopt并且bind之, shttpl就是返回的socket , 端口号runtime_vars.port = 8200 , 它来自minidlna.conf
if (shttpl < 0)
	DPRINTF(E_FATAL, L_GENERAL, "Failed to open socket for HTTP. EXITING\n");
DPRINTF(E_WARN, L_GENERAL, "HTTP listening on port %d\n", runtime_vars.port);
/* open socket for sending notifications */
if (OpenAndConfSSDPNotifySockets(snotify) < 0)  //初始化n_lan_addr个广播用socket
	DPRINTF(E_FATAL, L_GENERAL, "Failed to open sockets for sending SSDP notify "
			"messages. EXITING\n");
进入一个标准的select模型:
while (!quitting) //init quitting = 0
{
	/* Check if we need to send SSDP NOTIFY messages and do it if
	* needed */
	if (gettimeofday(&timeofday, 0) < 0)
	{
		DPRINTF(E_ERROR, L_GENERAL, "gettimeofday(): %s\n", strerror(errno));
		timeout.tv_sec = runtime_vars.notify_interval;
		timeout.tv_usec = 0;
	}
	else
	{
		/* the comparison is not very precise but who cares ? */
		if (timeofday.tv_
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值