1. 程式人生 > >live555學習筆記2-基礎類

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()函式:

  1. //改變目的地址的引數
  2. //newDestAddr是新的目的地址
  3. //newDestPort是新的目的埠
  4. //newDestTTL是新的TTL
  5. void Groupsock::changeDestinationParameters(  
  6.         struct in_addr const& newDestAddr,  
  7.         Port newDestPort,  
  8.         int newDestTTL)  
  9. {  
  10.     if (fDests == NULL)  
  11.         return;  
  12.     //獲取第一個目的地址(此處不是很明白:fDest是一個單向連結串列,每次新增一個目的地址,
  13.     //都會把它插入到最前目,難道這個函式僅改變最後一個新增的目的地址?)
  14.     struct in_addr destAddr = fDests->fGroupEId.groupAddress();  
  15.     if (newDestAddr.s_addr != 0) {  
  16.         if (newDestAddr.s_addr != destAddr.s_addr  
  17.                 && IsMulticastAddress(newDestAddr.s_addr))  
  18.         {  
  19.             //如果目的地址是一個多播地址,則離開老的多播組,加入新的多播組。
  20.             socketLeaveGroup(env(), socketNum(), destAddr.s_addr);  
  21.             socketJoinGroup(env(), socketNum(), newDestAddr.s_addr);  
  22.         }  
  23.         destAddr.s_addr = newDestAddr.s_addr;  
  24.     }  
  25.     portNumBits destPortNum = fDests->fGroupEId.portNum();  
  26.     if (newDestPort.num() != 0) {  
  27.         if (newDestPort.num() != destPortNum &&  
  28.                 IsMulticastAddress(destAddr.s_addr))  
  29.         {  
  30.             //如果埠也不一樣,則先更改本身socket的埠
  31.             //(其實是關掉原先的socket的,再以新埠開啟一個socket)。
  32.             changePort(newDestPort);  
  33.             //然後把新的socket加入到新的多播組。
  34.             // And rejoin the multicast group:
  35.             socketJoinGroup(env(), socketNum(), destAddr.s_addr);  
  36.         }  
  37.         destPortNum = newDestPort.num();  
  38.         fDests->fPort = newDestPort;  
  39.     }  
  40.     u_int8_t destTTL = ttl();  
  41.     if (newDestTTL != ~0)  
  42.         destTTL = (u_int8_t) newDestTTL;  
  43.     //目標地址的所有資訊都在fGroupEId中,所以改變成員fGroupEId。
  44.     fDests->fGroupEId = GroupEId(destAddr, destPortNum, destTTL);  
  45.     //(看起來這個函式好像只用於改變多播時的地址引數,
  46.     //以上分析是否合理,肯請高人指點)
  47. }  
轉載:http://blog.csdn.net/niu_gao/article/details/6906163