live555学习笔记2-基础类

来源:互联网 发布:tushare 获取股票数据 编辑:程序博客网 时间:2024/05/08 12:28

二 基础类

讲几个重要的基础类:

BasicUsageEnvironment和UsageEnvironment中的类都是用于整个系统的基础功能类.比如UsageEnvironment代表了整个系统运行的环境,它提供了错误记录和错误报告的功能,无论哪一个类要输出错误,就需要保存UsageEnvironment的指针.而TaskScheduler则提供了任务调度功能.整个程序的运行发动机就是它,它调度任务,执行任务(任务就是一个函数).TaskScheduler由于在全局中只有一个,所以保存在了UsageEnvironment中.而所有的类又都保存了UsageEnvironment的指针,所以谁想把自己的任务加入调度中,那是很容易的.在此还看到一个结论:整个live555(服务端)只有一个线程.


类HashTable:不用多说,实现了哈稀表.

类DelayQueue:译为"延迟队列",它是一个队列,每一项代表了一个要调度的任务(在它的fToken变量中保存).同时保存了这个任务离执行时间点的剩余时间.可以预见,它就是在TaskScheduler中用于管理调度任务的东西.注意,此队列中的任务只被执行一次!执行完后这一项即被无情抛弃!


类HandlerSet:Handler集合.Handler是什么呢?它是一种专门用于执行socket操作的任务(函数),HandlerSet被TaskScheduler用来管理所有的socket任务(增删改查).所以TaskScheduler中现在已调度两种任务了:socket任务(handlerSet)和延迟任务(DelayQueue).其实TaskScheduler还调度第三种任务:Event,介个后面再说.


类Groupsock:这个是放在单独的库Groupsock中。它封装了socket操作,增加了多播放支持和一对多单播的功能.但我只看到它对UDP的支持,好像不支持TCP。它管理着一个本地socket和多个目的地址,因为是UDP,所以只需知道对方地址和端口即可发送数据。Groupsock的构造函数有一个参数是struct in_addr const& groupAddr,在构造函数中首先会调用父类构造函数创建socket对象,然后判断这个地址,若是多播地址,则加入多播组。Groupsock的两个成员变量destRecord* fDests和DirectedNetInterfaceSet fMembers都表示目的地址集和,但我始终看不出DirectedNetInterfaceSet fMembers有什么用,且DirectedNetInterfaceSet是一个没有被继承的虚类,看起来fMembers没有什么用。仅fDesk也够用了,在addDestination()和removeDestination()函数中就是操作fDesk,添加或删除目的地址。

解释一下Groupsock::changeDestinationParameters()函数:

 
//改变目的地址的参数//newDestAddr是新的目的地址//newDestPort是新的目的端口//newDestTTL是新的TTLvoid Groupsock::changeDestinationParameters(struct in_addr const& newDestAddr,Port newDestPort,int newDestTTL){if (fDests == NULL)return;//获取第一个目的地址(此处不是很明白:fDest是一个单向链表,每次添加一个目的地址,//都会把它插入到最前目,难道这个函数仅改变最后一个添加的目的地址?)struct in_addr destAddr = fDests->fGroupEId.groupAddress();if (newDestAddr.s_addr != 0) {if (newDestAddr.s_addr != destAddr.s_addr&& IsMulticastAddress(newDestAddr.s_addr)){//如果目的地址是一个多播地址,则离开老的多播组,加入新的多播组。socketLeaveGroup(env(), socketNum(), destAddr.s_addr);socketJoinGroup(env(), socketNum(), newDestAddr.s_addr);}destAddr.s_addr = newDestAddr.s_addr;}portNumBits destPortNum = fDests->fGroupEId.portNum();if (newDestPort.num() != 0) {if (newDestPort.num() != destPortNum &&IsMulticastAddress(destAddr.s_addr)){//如果端口也不一样,则先更改本身socket的端口//(其实是关掉原先的socket的,再以新端口打开一个socket)。changePort(newDestPort);//然后把新的socket加入到新的多播组。// And rejoin the multicast group:socketJoinGroup(env(), socketNum(), destAddr.s_addr);}destPortNum = newDestPort.num();fDests->fPort = newDestPort;}u_int8_t destTTL = ttl();if (newDestTTL != ~0)destTTL = (u_int8_t) newDestTTL;//目标地址的所有信息都在fGroupEId中,所以改变成员fGroupEId。fDests->fGroupEId = GroupEId(destAddr, destPortNum, destTTL);//(看起来这个函数好像只用于改变多播时的地址参数,//以上分析是否合理,肯请高人指点)}

原创粉丝点击