live555學習筆記2-基礎類
二 基礎類
講幾個重要的基礎類:
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是新的TTL
- void 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);
- //(看起來這個函式好像只用於改變多播時的地址引數,
- //以上分析是否合理,肯請高人指點)
- }