国产日韩欧美一区二区三区三州_亚洲少妇熟女av_久久久久亚洲av国产精品_波多野结衣网站一区二区_亚洲欧美色片在线91_国产亚洲精品精品国产优播av_日本一区二区三区波多野结衣 _久久国产av不卡

?

一種應(yīng)用于UDP網(wǎng)絡(luò)通訊狀態(tài)機(jī)的智能定時(shí)器的軟件實(shí)現(xiàn)

2013-11-26 05:44李艷紅
關(guān)鍵詞:狀態(tài)機(jī)數(shù)組線程

李艷紅

(中南民族大學(xué)計(jì)算機(jī)科學(xué)學(xué)院,武漢430074)

在很多網(wǎng)絡(luò)應(yīng)用程序中,需要使用UDP來(lái)傳送消息和數(shù)據(jù),UDP傳輸是不可靠的,數(shù)據(jù)報(bào)可能會(huì)在傳送途中被丟棄.但是它也有很多優(yōu)點(diǎn),比如無(wú)連接、效率高、系統(tǒng)資源開(kāi)銷(xiāo)小、適用于防火墻穿透等,在互聯(lián)網(wǎng)實(shí)時(shí)通訊以及本機(jī)進(jìn)程間通訊中得以廣泛使用.設(shè)計(jì)UDP網(wǎng)絡(luò)通訊程序,需要解決丟包、重發(fā)、異步、并發(fā)等問(wèn)題.TCP和UDP在網(wǎng)絡(luò)通訊中都必不可少,他們有不同的特點(diǎn),有各自的適用范圍,均不可互相替代.UDP能夠在不建立連接的情況下收發(fā)數(shù)據(jù),也就是說(shuō)在防火墻允許的情況下,可以發(fā)送數(shù)據(jù)到任何地址,也可以接收任何地址發(fā)來(lái)的數(shù)據(jù).很多場(chǎng)合非常需要這種數(shù)據(jù)收發(fā)的方式.但是正是因?yàn)檫@個(gè)特點(diǎn),丟包的現(xiàn)象也是不可避免的.研究者們關(guān)注UDP傳輸?shù)目煽啃詥?wèn)題,并提出了改進(jìn)的算法[1,2],但是可靠性問(wèn)題從原理上講不可能完全解決.

在音視頻數(shù)據(jù)傳送時(shí),一定程度丟包率是允許的,不會(huì)對(duì)會(huì)話質(zhì)量造成很大的影響.但是傳送控制信息時(shí),需要用重發(fā)的方法來(lái)解決丟包問(wèn)題.重發(fā)涉及到重發(fā)的最大次數(shù)、每次重發(fā)的時(shí)間間隔,以及狀態(tài)機(jī)改變狀態(tài)后才收到的(遲來(lái)的)應(yīng)答包的處理方式等,這是異步操作必然要碰到的問(wèn)題.一般的網(wǎng)絡(luò)程序,往往需要同時(shí)處理一些并發(fā)的網(wǎng)絡(luò)通訊任務(wù),比如A終端與B終端進(jìn)行視頻會(huì)話,同時(shí)A終端還可能發(fā)送文件給C終端.

1 智能定時(shí)器的特點(diǎn)

定時(shí)器在過(guò)程控制中廣泛使用,針對(duì)一些特定的應(yīng)用環(huán)境,研究者們提出了相應(yīng)的方案和研究成果[3-8],本文重點(diǎn)研究智能定時(shí)器的軟件實(shí)現(xiàn).大多數(shù)情況下,程序中使用固定間隔值的定時(shí)器即可滿足定時(shí)的目的.VC、QT、JAVA等程序設(shè)計(jì)語(yǔ)言,無(wú)一例外實(shí)現(xiàn)了定時(shí)器類(lèi),提供了啟動(dòng)、停止、設(shè)置定時(shí)間隔值等方法,一般有一次性定時(shí)和重復(fù)定時(shí)兩種定時(shí)模式.但是,這些定時(shí)器不能滿足復(fù)雜的定時(shí)需求.例如運(yùn)用于退避算法,定時(shí)間隔需要變化、然后定時(shí)間隔再趨于穩(wěn)定的定時(shí)需求.而且,在不同場(chǎng)合間隔的變化方式也是不一樣的.為此,本文設(shè)計(jì)了一種稱(chēng)之為智能定時(shí)器的C++類(lèi),來(lái)解決這個(gè)問(wèn)題.

1.1 智能定時(shí)器類(lèi)的設(shè)計(jì)

該定時(shí)器類(lèi)的組成并不復(fù)雜,具體包括:一個(gè)數(shù)組、一個(gè)用于存放該數(shù)組元素個(gè)數(shù)的整數(shù)、一個(gè)時(shí)間戳、一個(gè)計(jì)數(shù)器、一個(gè)最大重試次數(shù)、判斷是否超時(shí)的函數(shù),以及判斷是否重試的函數(shù).

數(shù)組用來(lái)存放定時(shí)的間隔(超時(shí)值),也即每一次重試等待的時(shí)間.數(shù)組長(zhǎng)度可長(zhǎng)可短,由重試的頻度變化策略決定,比如發(fā)送一個(gè)UDP包后,如果沒(méi)收到應(yīng)答,則需要按 2s、4s、8s、16s、16s 這樣的間隔重發(fā),那么該數(shù)組就是[0,2,4,8,16,16].由于數(shù)組是由構(gòu)造函數(shù)的參數(shù)傳入的,構(gòu)造函數(shù)得到的是該數(shù)組的地址,在函數(shù)中無(wú)法求得其元素個(gè)數(shù),所以需要將元素個(gè)數(shù)也作為參數(shù)傳入構(gòu)造函數(shù).在構(gòu)造函數(shù)中,將數(shù)組地址及其元素個(gè)數(shù)保存到成員變量中.

時(shí)間戳用來(lái)存放上次重試(重發(fā))的系統(tǒng)時(shí)間.計(jì)數(shù)器用來(lái)統(tǒng)計(jì)重試的次數(shù).最大重試次數(shù)用來(lái)判斷是否超時(shí),這里的超時(shí)表示重試結(jié)束.如果最大重試次數(shù)為0,則表示需要無(wú)限次重試.

如果計(jì)數(shù)器大于最大重試次數(shù),并且最大重試次數(shù)大于0,則表示已經(jīng)超時(shí).判斷是否需要重試的方法是,取出當(dāng)前計(jì)數(shù)器對(duì)應(yīng)數(shù)組元素的值,然后用當(dāng)前系統(tǒng)時(shí)間減去時(shí)間戳的值,如果差值大于等于數(shù)組元素值,則表示需要重試.此時(shí),將當(dāng)前系統(tǒng)時(shí)間賦值給時(shí)間戳,作為下次判斷的依據(jù).

定時(shí)器類(lèi)的設(shè)計(jì)具體如下:

1.2 智能定時(shí)器工作原理

上文所述的定時(shí)器是一個(gè)被動(dòng)對(duì)象,也即沒(méi)有自己的線程,需要在定時(shí)器線程以及狀態(tài)機(jī)的配合下才能發(fā)揮作用.沒(méi)有設(shè)計(jì)自己的線程,是為了節(jié)省系統(tǒng)的開(kāi)銷(xiāo).因?yàn)橐粋€(gè)稍微復(fù)雜的系統(tǒng),可能需要多個(gè)定時(shí)器,如果每個(gè)定時(shí)器都有一個(gè)線程在運(yùn)行,總體上會(huì)增加CPU空轉(zhuǎn)的時(shí)間.

狀態(tài)機(jī)一般是指有限狀態(tài)機(jī),由一系列的狀態(tài)、事件、條件、動(dòng)作組成.在某一時(shí)刻,狀態(tài)機(jī)只能處于某個(gè)狀態(tài),稱(chēng)為當(dāng)前狀態(tài).當(dāng)發(fā)生某個(gè)事件時(shí),如果條件滿足,則狀態(tài)機(jī)的狀態(tài)將發(fā)生改變,這個(gè)改變稱(chēng)為狀態(tài)轉(zhuǎn)移.狀態(tài)轉(zhuǎn)移往往伴隨著一些動(dòng)作(任務(wù))的執(zhí)行.

線程是利用CPU時(shí)間片輪轉(zhuǎn)來(lái)獲得執(zhí)行權(quán)的代碼片段.在多數(shù)線程的使用中,這個(gè)代碼片段會(huì)設(shè)計(jì)成循環(huán)體,只有在特殊條件下才退出循環(huán)來(lái)結(jié)束線程.每一次循環(huán)內(nèi),調(diào)用狀態(tài)機(jī)處理函數(shù),處理一次狀態(tài)機(jī).如果系統(tǒng)需要多個(gè)狀態(tài)機(jī),則每個(gè)狀態(tài)機(jī)都處理一次,調(diào)用完所有的處理函數(shù)后是短暫的休眠.休眠的時(shí)間與定時(shí)器的精度相關(guān),比如精度為20ms則休眠20ms,也即預(yù)定1s的定時(shí),那么實(shí)際的定時(shí)間隔為1000~1020ms.除非是實(shí)時(shí)系統(tǒng)需要精確到微秒,一般的應(yīng)用,精度為20~100ms就可以滿足要求.

狀態(tài)機(jī)處理函數(shù)因?yàn)橐幚砗芏酄顟B(tài),適合用switch…case構(gòu)建,該函數(shù)被調(diào)用時(shí),執(zhí)行的代碼是狀態(tài)機(jī)當(dāng)前狀態(tài)的case,在此狀態(tài)中,如果有重傳,或者超時(shí)狀態(tài)轉(zhuǎn)移的需求,則可分別調(diào)用isNextStep()和isTimeOut()來(lái)判斷.當(dāng)isTimeOut返回true時(shí),表示狀態(tài)機(jī)需要轉(zhuǎn)移到新的狀態(tài),而isNextStep返回true時(shí),表示在當(dāng)前狀態(tài)下需要重復(fù)執(zhí)行某些任務(wù).在isNextStep被調(diào)用時(shí),計(jì)數(shù)器count和上次訪問(wèn)last time才會(huì)被更新.這表明,增加智能定時(shí)器只是增加少量?jī)?nèi)存的使用,不會(huì)增加系統(tǒng)的CPU資源消耗.

狀態(tài)機(jī)的狀態(tài)轉(zhuǎn)移,除了超時(shí)的原因外,更多的是人機(jī)交互事件和外部系統(tǒng)事件觸發(fā)的,比如用戶點(diǎn)擊“上線”按鈕,或者是收到服務(wù)器的應(yīng)答信息.

2 智能定時(shí)器運(yùn)用實(shí)例的具體實(shí)現(xiàn)

本文以音視頻會(huì)話終端軟件的登錄過(guò)程作為實(shí)例,來(lái)說(shuō)明智能定時(shí)器的功能和運(yùn)用方法.程序分終端程序和服務(wù)器端程序,均在Linux平臺(tái)開(kāi)發(fā)和運(yùn)行,采用C++語(yǔ)言編程.

2.1 登錄狀態(tài)機(jī)

終端登錄的過(guò)程用狀態(tài)機(jī)表示,如圖1所示.

圖1 終端登錄狀態(tài)機(jī)Fig.1 Terminal login state machine

該狀態(tài)機(jī)有“離線”、“請(qǐng)求登錄服務(wù)器地址”、“登錄請(qǐng)求”、“檢測(cè)防火墻”、“檢測(cè) NAT”、“心跳”6個(gè)狀態(tài).除了離線狀態(tài),其余狀態(tài)都使用了定時(shí)器.這些定時(shí)器中,只有在心跳狀態(tài)下終端才會(huì)以固定的時(shí)間間隔發(fā)送心跳包,其余狀態(tài)的終端都要按照一定的退避算法來(lái)重發(fā)數(shù)據(jù).按退避算法的方式來(lái)重發(fā)的原因是,如果服務(wù)器忙于處理其他任務(wù),不能及時(shí)給終端返回應(yīng)答,終端應(yīng)當(dāng)適當(dāng)放慢重試的頻率;又由于終端向服務(wù)器發(fā)送的請(qǐng)求數(shù)據(jù)可能在網(wǎng)絡(luò)上丟失,那么終端也不能無(wú)限制等待,希望服務(wù)器最終會(huì)返回應(yīng)答.

2.2 定時(shí)間隔數(shù)組及定時(shí)器對(duì)象

根據(jù)登錄過(guò)程的狀態(tài)機(jī),制定定時(shí)器策略.終端登錄過(guò)程共需要3種定時(shí)器:1)登錄請(qǐng)求定時(shí)器,分時(shí)復(fù)用于3個(gè)狀態(tài):獲取登錄服務(wù)器地址、登錄請(qǐng)求、檢測(cè)NAT;2)防火墻檢測(cè)定時(shí)器,用于檢測(cè)防火墻;3)心跳維持定時(shí)器,用于心跳包定時(shí)發(fā)送.如表1所示.

表1 定時(shí)策略表Tab.1 Timing strategy table

根據(jù)定時(shí)策略表,定義3個(gè)數(shù)組:

unsigned int tmLogin[5]={0,2000,4000,4000,8000};

unsigned int tmFwDetect[6]={0,500,1000,2000,4000,8000};

unsigned int tmHeartBeat[2]={0,16000};

然后,聲明智能定時(shí)器實(shí)例,構(gòu)造函數(shù)中傳入數(shù)組及其元素個(gè)數(shù):

startTimer stLogin(tmLogin,sizeof(tmLogin)/sizeof(tmLogin[0]));

startTimer stFwDetect (tmFwDetect,sizeof(tmFwDetect)/sizeof(tmFwDetect[0]));

startTimer stHeartBeat(tmHeartBeat,sizeof(tmHeartBeat)/sizeof(tmHeartBeat[0]));

2.3 登錄過(guò)程中所涉及的算法

登錄過(guò)程涉及到3個(gè)算法,分別是:定時(shí)器線程、登錄狀態(tài)機(jī)處理函數(shù)、服務(wù)器應(yīng)答處理.

(1)定時(shí)器線程算法.

Function TimerThread

pre-condition:sm is initialized to offline

1 While program not quitting do{

2 smLoginProcess();

3 sleep 100 ms;

4}

(2)登錄狀態(tài)機(jī)處理函數(shù)算法.

Function smLoginProcess

1switch(sm){

2 case offline:

3 break;

4 case login_server_req:

5 if(stLogin.isNextStep()){

6 send CMD_LB_LOGINSERVERREQ packet to load-balance server;

7 }

8 break;

9 case login_req:

10 if(stLogin.isTimeOut()){//如果超時(shí)則返回到login_server_req狀態(tài)

11 sm=login_server_req;

12 stLogin.reset(0);

13 break;

14 }

15 if(stLogin.isNextStep()){//否則如果時(shí)間間隔已滿則重發(fā)登錄請(qǐng)求到登錄服務(wù)器

16 send CMD_NAT_LOGINREQ packet to login server;

17 }

18 break;

19 case firewall_detecting:

20 如果stLogin超時(shí)(5次重試無(wú)應(yīng)答)則說(shuō)明有防火墻,記錄防火墻特性,復(fù)位stFwDetect,設(shè)置狀態(tài)為 nat_detecting.否則如果時(shí)間間隔已滿則重發(fā)防火墻檢測(cè)請(qǐng)求.

21 break;

22 case nat_detecting:

23 如果stFwDetect超時(shí)則返回login_server_req狀態(tài).否則如果時(shí)間間隔已滿則重發(fā)NAT檢測(cè)請(qǐng)求.

24 break;

25 case heat_beating:

26 如果超時(shí)則返回login_server_req狀態(tài),否則如果時(shí)間間隔已滿則重發(fā)心跳包.

27 break;

28 }

(3)服務(wù)器應(yīng)答處理算法片段.

Function onServerAck(char*pkt)

1 switch(cmd in pkt){//所有服務(wù)器返回的應(yīng)答包中均含有cmd(命令字)

2case CMD_LB_LOGINSERVERACK:

3 if(login_server_req){//該應(yīng)答包只有在login_server_req狀態(tài)下才有效

4 sm=login_req;//更新?tīng)顟B(tài)機(jī)的當(dāng)前狀態(tài)為login_req

5 stLogin.reset(10);//重置定時(shí)器 stLogin,表示在login_req狀態(tài)最多重發(fā)10次.

6 get ip,port of login server from pkt;//取得應(yīng)答包中所含登錄服務(wù)器的地址

7 }

8 break;

9case CMD_NAT_LOGINACK:

10 …(略)

由于篇幅所限,不能完整描述這3個(gè)算法對(duì)所有狀態(tài)和所有服務(wù)器應(yīng)答包的處理情況,以下重點(diǎn)介紹終端由offline(離線)狀態(tài)和login_server_req(獲取登錄服務(wù)器地址)狀態(tài)相關(guān)的處理.

首先需要注意的是定時(shí)器線程算法TimerThread,該線程每隔100ms會(huì)執(zhí)行一次狀態(tài)機(jī)處理函數(shù)smLoginProcess.

終端程序初始化后,狀態(tài)機(jī)處于offline(離線).在offline狀態(tài),smLoginProcess處理函數(shù)不做任何操作,立即返回(第3行代碼).只有人機(jī)交互才能改變offline的狀態(tài),比如通過(guò)按鈕發(fā)出“上線”請(qǐng)求,相應(yīng)的代碼會(huì)將狀態(tài)機(jī)的狀態(tài)由offline轉(zhuǎn)移到login_server_req,并調(diào)用 stLogin.reset(0)復(fù)位定時(shí)器,也即在該狀態(tài)下將無(wú)限次地重試,直到從負(fù)載均衡服務(wù)器取到登錄服務(wù)器地址為止.

狀態(tài)機(jī)處理函數(shù)smLoginProcess對(duì)login_server_req狀態(tài)的處理見(jiàn) 4~8行.在此調(diào)用 stLogin.isNextStep來(lái)判斷是否該發(fā)送CMD_LB_LOGINSERVERREQ到負(fù)載均衡服務(wù)器.在smartTimer的isNextStep代碼中可以看到,如果當(dāng)前時(shí)間減去上次重試的時(shí)間大于當(dāng)前重試間隔值,會(huì)返回 true.在 login_server_req 狀態(tài)下,stLogin.isNextStep返回true時(shí),程序?qū)?zhí)行第6行所示的動(dòng)作,發(fā)送CMD_LB_LOGINSERVERREQ到負(fù)載均衡服務(wù)器.

如果一直沒(méi)有收到負(fù)載均衡服務(wù)器的應(yīng)答,則狀態(tài)機(jī)處理函數(shù)將永遠(yuǎn)執(zhí)行4~8行的代碼.負(fù)載均衡服務(wù)器的應(yīng)答在算法onServerAck的2~8行中處理,負(fù)載均衡服務(wù)器返回的應(yīng)答包中包含了登錄服務(wù)器的地址,這個(gè)應(yīng)答包只有在終端的狀態(tài)為login_server_req時(shí)才被處理,在其他狀態(tài)則被忽略.處理方法是:1)狀態(tài)機(jī)變?yōu)閘ogin_req;2)將定時(shí)器stLogin復(fù)位為10 次超時(shí),這10 次的間隔值分別為0、2、4、4、8、8、8、8、8、8s;3)從應(yīng)答包中取出登錄服務(wù)器的地址.

狀態(tài)機(jī)處理函數(shù)smLoginProcess對(duì)login_req狀態(tài)的處理見(jiàn)9~18行.先調(diào)用stLogin.isTimeOut,如果超時(shí)則狀態(tài)回轉(zhuǎn)到login_server_req重新取登錄服務(wù)器地址.如果沒(méi)有超時(shí),則調(diào)用stLogin.isNextStep判斷是否需要重試發(fā)送登錄請(qǐng)求.

以上3個(gè)算法組成的代碼框架,除了實(shí)現(xiàn)數(shù)據(jù)重發(fā),也體現(xiàn)了并發(fā)、同步操作的理念.終端發(fā)出請(qǐng)求包,服務(wù)器返回應(yīng)答包是異步操作,不能設(shè)計(jì)成函數(shù)調(diào)用得到返回值的方式.smLoginProcess中發(fā)送請(qǐng)求,而在onServerAck中處理應(yīng)答,使用了異步處理的模式.終端完成登錄后進(jìn)入心跳狀態(tài),在心跳狀態(tài)終端每16s向服務(wù)器發(fā)送一次心跳包.如果用戶發(fā)起音視頻會(huì)話,那么心跳包和會(huì)話信令包以及音視頻數(shù)據(jù)包就需要并發(fā)處理.

3 結(jié)語(yǔ)

本文介紹了一種能夠處理復(fù)雜狀態(tài)機(jī)和程序邏輯的智能定時(shí)器,該智能定時(shí)器以一個(gè)類(lèi)的形式進(jìn)行封裝.智能定時(shí)器實(shí)例化時(shí),從構(gòu)造函數(shù)傳入預(yù)設(shè)的定時(shí)數(shù)組,數(shù)組的元素個(gè)數(shù)可根據(jù)需要進(jìn)行設(shè)定,每個(gè)元素的值代表某個(gè)操作重復(fù)執(zhí)行的等待時(shí)間.該智能定時(shí)器屬于被動(dòng)對(duì)象(沒(méi)有自己的線程),因此需要在線程中去查詢是否重復(fù)執(zhí)行某操作,或者去查詢是否超時(shí).本文所用的定時(shí)器線程和狀態(tài)機(jī)處理函數(shù),是支撐智能定時(shí)器的線程、狀態(tài)機(jī)處理的典型代碼框架.千變?nèi)f化的狀態(tài)機(jī)模型,均可按照此框架來(lái)構(gòu)建程序.最后實(shí)現(xiàn)了將智能定時(shí)器應(yīng)用于實(shí)時(shí)通訊軟件系統(tǒng)的登錄過(guò)程,實(shí)驗(yàn)結(jié)果表明所設(shè)計(jì)的智能定時(shí)器能精確控制UDP包的重發(fā).

[1]李 國(guó),鞏光志,王冬冬.一種提高UDP可靠性的數(shù)據(jù)傳輸方法研究[J].中國(guó)民航大學(xué)學(xué)報(bào),2012(01):41-45.

[2]王艷芳,戴 永,劉東華,等.基于UDP的數(shù)據(jù)可靠傳輸技術(shù)研究與應(yīng)用[J].計(jì)算機(jī)工程與應(yīng)用,2010(03):105-108.

[3]孫宏旭,邢 薇,陶 林.基于有限狀態(tài)機(jī)的模型轉(zhuǎn)換方法的研究[J].計(jì)算機(jī)技術(shù)與發(fā)展,2012(02):10-13.

[4]李慶華,陳志剛,鄧曉衡.基于線性均方誤差的無(wú)線自組網(wǎng)TCP定時(shí)器改進(jìn)[J].中南大學(xué)學(xué)報(bào):自然科學(xué)版,2012(05):1780-1786.

[5]朱正發(fā),陳琳.一種嵌入式基帶系統(tǒng)定時(shí)器裝置的研究[J].單片機(jī)與嵌入式系統(tǒng)應(yīng)用,2012(11):12-14.

[6]朱旭光.單片機(jī)定時(shí)器應(yīng)用探討[J].自動(dòng)化技術(shù)與應(yīng)用,2012(01):99-103.

[7]王秀霞.基于555定時(shí)器的開(kāi)關(guān)電源的設(shè)計(jì)[J].微計(jì)算機(jī)信息,2012(01):76-78.

[8]任君玉,黎國(guó)文.網(wǎng)絡(luò)中的定時(shí)器技術(shù)[J].電腦知識(shí)與技術(shù),2011(21):5094-5095.

猜你喜歡
狀態(tài)機(jī)數(shù)組線程
JAVA稀疏矩陣算法
基于C#線程實(shí)驗(yàn)探究
JAVA玩轉(zhuǎn)數(shù)學(xué)之二維數(shù)組排序
基于國(guó)產(chǎn)化環(huán)境的線程池模型研究與實(shí)現(xiàn)
基于有限狀態(tài)機(jī)的交會(huì)對(duì)接飛行任務(wù)規(guī)劃方法
線程池調(diào)度對(duì)服務(wù)器性能影響的研究*
基于Spring StateMachine的有限狀態(tài)機(jī)應(yīng)用研究
更高效用好 Excel的數(shù)組公式
尋找勾股數(shù)組的歷程
基于反熔絲FPGA的有限狀態(tài)機(jī)加固設(shè)計(jì)