二 基礎(chǔ)類
講幾個(gè)重要的基礎(chǔ)類:
BasicUsageEnvironment和UsageEnvironment中的類都是用于整個(gè)系統(tǒng)的基礎(chǔ)功能類.比如UsageEnvironment代表了整個(gè)系統(tǒng)運(yùn)行的環(huán)境,它提供了錯(cuò)誤記錄和錯(cuò)誤報(bào)告的功能,無論哪一個(gè)類要輸出錯(cuò)誤,就需要保存UsageEnvironment的指針.而TaskScheduler則提供了任務(wù)調(diào)度功能.整個(gè)程序的運(yùn)行發(fā)動(dòng)機(jī)就是它,它調(diào)度任務(wù),執(zhí)行任務(wù)(任務(wù)就是一個(gè)函數(shù)).TaskScheduler由于在全局中只有一個(gè),所以保存在了UsageEnvironment中.而所有的類又都保存了UsageEnvironment的指針,所以誰想把自己的任務(wù)加入調(diào)度中,那是很容易的.在此還看到一個(gè)結(jié)論:整個(gè)live555(服務(wù)端)只有一個(gè)線程.
類HashTable:不用多說,實(shí)現(xiàn)了哈稀表.
類DelayQueue:譯為"延遲隊(duì)列",它是一個(gè)隊(duì)列,每一項(xiàng)代表了一個(gè)要調(diào)度的任務(wù)(在它的fToken變量中保存).同時(shí)保存了這個(gè)任務(wù)離執(zhí)行時(shí)間點(diǎn)的剩余時(shí)間.可以預(yù)見,它就是在TaskScheduler中用于管理調(diào)度任務(wù)的東西.注意,此隊(duì)列中的任務(wù)只被執(zhí)行一次!執(zhí)行完后這一項(xiàng)即被無情拋棄!
類HandlerSet:Handler集合.Handler是什么呢?它是一種專門用于執(zhí)行socket操作的任務(wù)(函數(shù)),HandlerSet被TaskScheduler用來管理所有的socket任務(wù)(增刪改查).所以TaskScheduler中現(xiàn)在已調(diào)度兩種任務(wù)了:socket任務(wù)(handlerSet)和延遲任務(wù)(DelayQueue).其實(shí)TaskScheduler還調(diào)度第三種任務(wù):Event,介個(gè)后面再說.
類Groupsock:這個(gè)是放在單獨(dú)的庫Groupsock中。它封裝了socket操作,增加了多播放支持和一對多單播的功能.但我只看到它對UDP的支持,好像不支持TCP。它管理著一個(gè)本地socket和多個(gè)目的地址,因?yàn)槭荱DP,所以只需知道對方地址和端口即可發(fā)送數(shù)據(jù)。Groupsock的構(gòu)造函數(shù)有一個(gè)參數(shù)是struct in_addr const& groupAddr,在構(gòu)造函數(shù)中首先會(huì)調(diào)用父類構(gòu)造函數(shù)創(chuàng)建socket對象,然后判斷這個(gè)地址,若是多播地址,則加入多播組。Groupsock的兩個(gè)成員變量destRecord* fDests和DirectedNetInterfaceSet fMembers都表示目的地址集和,但我始終看不出DirectedNetInterfaceSet fMembers有什么用,且DirectedNetInterfaceSet是一個(gè)沒有被繼承的虛類,看起來fMembers沒有什么用。僅fDesk也夠用了,在addDestination()和removeDestination()函數(shù)中就是操作fDesk,添加或刪除目的地址。
解釋一下Groupsock::changeDestinationParameters()函數(shù):
[cpp] view plain copy//改變目的地址的參數(shù) //newDestAddr是新的目的地址 //newDestPort是新的目的端口 //newDestTTL是新的TTL void Groupsock::changeDestinationParameters( struct in_addr const& newDestAddr, Port newDestPort, int newDestTTL) { if (fDests == NULL) return; //獲取第一個(gè)目的地址(此處不是很明白:fDest是一個(gè)單向鏈表,每次添加一個(gè)目的地址, //都會(huì)把它插入到最前目,難道這個(gè)函數(shù)僅改變最后一個(gè)添加的目的地址?) struct in_addr destAddr = fDests->fGroupEId.groupAddress(); if (newDestAddr.s_addr != 0) { if (newDestAddr.s_addr != destAddr.s_addr && IsMulticastAddress(newDestAddr.s_addr)) { //如果目的地址是一個(gè)多播地址,則離開老的多播組,加入新的多播組。 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的端口 //(其實(shí)是關(guān)掉原先的socket的,再以新端口打開一個(gè)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; //目標(biāo)地址的所有信息都在fGroupEId中,所以改變成員fGroupEId。 fDests->fGroupEId = GroupEId(destAddr, destPortNum, destTTL); //(看起來這個(gè)函數(shù)好像只用于改變多播時(shí)的地址參數(shù), //以上分析是否合理,肯請高人指點(diǎn)) }
新聞熱點(diǎn)
疑難解答