物聯(lián)網(wǎng).NET開(kāi)發(fā)(第二版) 課件 張勇 項(xiàng)目5-9 智能大棚控制系統(tǒng) - 智能家居系統(tǒng)_第1頁(yè)
物聯(lián)網(wǎng).NET開(kāi)發(fā)(第二版) 課件 張勇 項(xiàng)目5-9 智能大棚控制系統(tǒng) - 智能家居系統(tǒng)_第2頁(yè)
物聯(lián)網(wǎng).NET開(kāi)發(fā)(第二版) 課件 張勇 項(xiàng)目5-9 智能大棚控制系統(tǒng) - 智能家居系統(tǒng)_第3頁(yè)
物聯(lián)網(wǎng).NET開(kāi)發(fā)(第二版) 課件 張勇 項(xiàng)目5-9 智能大棚控制系統(tǒng) - 智能家居系統(tǒng)_第4頁(yè)
物聯(lián)網(wǎng).NET開(kāi)發(fā)(第二版) 課件 張勇 項(xiàng)目5-9 智能大棚控制系統(tǒng) - 智能家居系統(tǒng)_第5頁(yè)
已閱讀5頁(yè),還剩193頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

智能大棚控制系統(tǒng)任務(wù)1:線程實(shí)現(xiàn)頁(yè)面刷新任務(wù)2:委托實(shí)現(xiàn)頁(yè)面刷新任務(wù)3:事件引發(fā)頁(yè)面刷新項(xiàng)目五智能大棚控制系統(tǒng)實(shí)現(xiàn)了智能大棚的溫度、光敏數(shù)值監(jiān)控及控制功能,本項(xiàng)目模擬實(shí)現(xiàn)了大棚環(huán)境溫度及光敏的監(jiān)測(cè)、通過(guò)數(shù)據(jù)分析控制風(fēng)扇和燈光的打開(kāi)和關(guān)閉控制,為智能農(nóng)業(yè)提供解決方案。Windows為多任務(wù)操作系統(tǒng),操作系統(tǒng)在處理任務(wù)時(shí)采用多線程技術(shù),C#引入了多線程技術(shù),通過(guò)多線程技術(shù)能夠提高程序的執(zhí)行效率,減少系統(tǒng)資源的浪費(fèi)。面向?qū)ο蟮某绦蛟O(shè)計(jì)在圖形用戶界面開(kāi)發(fā)中采用了事件處理機(jī)制,通過(guò)事件處理實(shí)現(xiàn)程序的交互,.NETFramework在處理事件中引入了委托的概念,委托在C#中是一個(gè)特殊的對(duì)象類型,委托的使用是安全的、面向?qū)ο蟮?,通過(guò)委托實(shí)現(xiàn)方法的調(diào)用。項(xiàng)目引入掌握線程的定義及使用掌握委托的定義及使用掌握事件的定義及使用學(xué)習(xí)目標(biāo)項(xiàng)目運(yùn)行后,自動(dòng)監(jiān)測(cè)大棚內(nèi)環(huán)境溫度及光敏數(shù)據(jù),數(shù)據(jù)每隔5秒自動(dòng)進(jìn)行刷新,風(fēng)扇狀態(tài)和RGB狀態(tài)初始處于“關(guān)閉”狀態(tài),程序啟動(dòng)運(yùn)行效果如圖5-1所示:項(xiàng)目描述如果監(jiān)測(cè)到溫度超過(guò)30度,則自動(dòng)打開(kāi)風(fēng)扇,風(fēng)扇變?yōu)椤按蜷_(kāi)”狀態(tài),如果監(jiān)測(cè)到光敏數(shù)據(jù)超過(guò)120,則自動(dòng)打開(kāi)RGB燈,RGB燈變?yōu)椤按蜷_(kāi)”狀態(tài),如圖5-2所示:如果監(jiān)測(cè)到溫度低于30度,則自動(dòng)關(guān)閉風(fēng)扇,風(fēng)扇變?yōu)椤瓣P(guān)閉”狀態(tài),如果監(jiān)測(cè)到光敏數(shù)據(jù)低于120,則自動(dòng)關(guān)閉RGB燈,RGB燈變?yōu)椤瓣P(guān)閉”狀態(tài),,如圖5-3所示:項(xiàng)目描述任務(wù)1:線程實(shí)現(xiàn)頁(yè)面刷新任務(wù)2:委托實(shí)現(xiàn)頁(yè)面刷新任務(wù)3:事件引發(fā)頁(yè)面刷新工作任務(wù)任務(wù)描述

項(xiàng)目運(yùn)行通過(guò)隨機(jī)函數(shù)模擬生成溫度及光敏隨機(jī)數(shù)據(jù),通過(guò)后臺(tái)線程獲取隨機(jī)數(shù)據(jù)并顯示,數(shù)據(jù)每隔5秒自動(dòng)刷新,項(xiàng)目運(yùn)行過(guò)程中對(duì)數(shù)據(jù)進(jìn)行分析,如果溫度超過(guò)30度,則打開(kāi)風(fēng)扇,否則關(guān)閉風(fēng)扇,如果如果光敏大于100,則打開(kāi)RGB燈,否則關(guān)閉RGB燈。任務(wù)1線程實(shí)現(xiàn)頁(yè)面刷新1.線程

線程(英語(yǔ):thread)是操作系統(tǒng)能夠進(jìn)行運(yùn)算調(diào)度的最小單位,一個(gè)進(jìn)程中可以并發(fā)多個(gè)線程,每條線程并行執(zhí)行不同的任務(wù),多個(gè)線程并發(fā)執(zhí)行能提高程序執(zhí)行效率,C#支持多線程并發(fā),C#能過(guò)命名空間System.Threading支持線程對(duì)象,Thread類用來(lái)創(chuàng)建線程對(duì)象,如:Threadt1=newThread(show);Show為要執(zhí)行的方法,Thread類的常用屬性如表所示:知識(shí)引入任務(wù)1線程實(shí)現(xiàn)頁(yè)面刷新屬性說(shuō)明CurrentContext獲取線程正在其中執(zhí)行的當(dāng)前上下文CurrentThread獲取當(dāng)前正在運(yùn)行的線程IsAlive判斷當(dāng)前線程是否處于活動(dòng)狀態(tài)IsBackground獲取或設(shè)置取或設(shè)置線程是否為后臺(tái)線程。Name獲取或設(shè)置線程的名稱ThreadState當(dāng)前線程的狀態(tài)1.線程

Thread類的常用方法如表5-2所示:知識(shí)引入任務(wù)1線程實(shí)現(xiàn)頁(yè)面刷新方法說(shuō)明publicvoidAbort()終止此線程的過(guò)程,調(diào)用此方法通常會(huì)終止此線程publicvoidInterrupt()中斷處于WaitSleepJoin線程狀態(tài)的線程publicvoidJoin()阻塞調(diào)用線程publicstaticvoidResetAbort()取消為當(dāng)前線程請(qǐng)求的AbortpublicvoidStart()線程啟動(dòng)運(yùn)行publicstaticvoidSleep()讓線程暫停一段時(shí)間1.線程知識(shí)引入任務(wù)1線程實(shí)現(xiàn)頁(yè)面刷新【例5-1】線程的定義

staticvoidMain(string[]args){Thread

t=newThread(show);t.Start();for(inti=0;i<50;i++){Console.WriteLine("ok");}}staticvoidshow(){for(inti=0;i<50;i++){Console.WriteLine("hello");}}1.線程知識(shí)引入任務(wù)1線程實(shí)現(xiàn)頁(yè)面刷新【例5-2】線程的方法調(diào)用

staticvoidMain(string[]args){Threadt=newThread(print);t.Start();}publicstaticvoidprint(){for(inti=5;i>0;i--){Console.WriteLine(i);Thread.Sleep(i*1000);}

}2.Random類知識(shí)引入任務(wù)1線程實(shí)現(xiàn)頁(yè)面刷新Random類表示隨機(jī)數(shù)生成器,通過(guò)Random類可以產(chǎn)生滿足條件的隨機(jī)數(shù),Random類有兩種構(gòu)造方法,分別為:Random():表示根據(jù)當(dāng)前系統(tǒng)時(shí)間為種子,產(chǎn)生隨機(jī)數(shù)Random(Int32):表示根據(jù)設(shè)定的種子產(chǎn)生隨機(jī)數(shù)方法

說(shuō)明Next()返回一個(gè)非負(fù)隨機(jī)整數(shù)Next(Int32)返回一個(gè)小于所指定最大值的非負(fù)隨機(jī)整數(shù)Next(Int32,Int32)返回在指定范圍內(nèi)的任意整數(shù)NextDouble()返回一個(gè)大于或等于0.0且小于1.0的隨機(jī)浮點(diǎn)數(shù)Sample()返回一個(gè)大于或等于0.0且小于1.0的隨機(jī)浮點(diǎn)數(shù),該方法為protected,訪問(wèn)級(jí)別不同,其它方法為public。2.Random類知識(shí)引入任務(wù)1線程實(shí)現(xiàn)頁(yè)面刷新【例5-3】Random類生成隨機(jī)數(shù)

staticvoidMain(string[]args){Randomrand=newRandom();Console.WriteLine(rand.Next());Console.WriteLine(rand.Next(5));Console.WriteLine(rand.Next(5,10));Console.WriteLine(rand.NextDouble());

}3.跨線程更新UI知識(shí)引入任務(wù)1線程實(shí)現(xiàn)頁(yè)面刷新在多線程操作中,如果子線程需要訪問(wèn)主線程創(chuàng)建的控件,特別是子線程希望隨時(shí)更新主線程創(chuàng)建控件的外觀,在.NET2.0后系統(tǒng)可能會(huì)拋出異常,導(dǎo)致程序不能運(yùn)行。這主要是出于安全考慮,CheckForIllegalCrossThreadCalls的值在.NET2.0后默認(rèn)為true,表示在訪問(wèn)非創(chuàng)建線程控件時(shí)會(huì)進(jìn)行安全考慮,系統(tǒng)將拋出異常。3.跨線程更新UI知識(shí)引入任務(wù)1線程實(shí)現(xiàn)頁(yè)面刷新【例5-4】實(shí)現(xiàn)當(dāng)點(diǎn)擊按鈕“button1”后,上面的標(biāo)簽在“紅色”變?yōu)椤八{(lán)色”,并且每隔2秒在兩種顏色之間進(jìn)行切換。3.跨線程更新UI知識(shí)引入任務(wù)1線程實(shí)現(xiàn)頁(yè)面刷新【例5-4】privatevoidbutton1_Click(objectsender,EventArgse){Threadt=newThread(setText);t.IsBackground=true;t.Start();}privatevoidsetText(){while(true){if(label1.Text.Equals("紅色")){label1.Text="藍(lán)色";}else{label1.Text="紅色";}Thread.Sleep(2000); }

}任務(wù)1

線程實(shí)現(xiàn)頁(yè)面刷新任務(wù)實(shí)現(xiàn)1.新建Windows窗體應(yīng)用程序項(xiàng)目,添加控件及屬性設(shè)置如表所示:控件屬性值Form1Text智能大棚控制系統(tǒng)Form1Size480,360Label1Text智能大棚控制系統(tǒng)Label2Text當(dāng)前溫度Label3TextnullLabel3NamelblTempLabel4Text當(dāng)前光敏Label4NamelblPhotoLabel5Text風(fēng)扇狀態(tài)Label6Text關(guān)閉Label6NamelblFsLabel7TextRGB燈狀態(tài)Label8Text關(guān)閉Label8NamelblRgb任務(wù)1

線程實(shí)現(xiàn)頁(yè)面刷新任務(wù)實(shí)現(xiàn)2.添加頁(yè)面事件代碼如下:publicForm1(){InitializeComponent();Control.CheckForIllegalCrossThreadCalls=false;}privatevoidForm1_Load(objectsender,EventArgse){Threadt=newThread(setVal);t.IsBackground=true;t.Start();}//隨機(jī)生成溫度privateintgetWd(){intresult=-1;Randomrand=newRandom();result=rand.Next(20,35);returnresult;}任務(wù)1

線程實(shí)現(xiàn)頁(yè)面刷新任務(wù)實(shí)現(xiàn)2.添加頁(yè)面事件代碼如下://隨機(jī)生成光敏privateintgetPhoto(){intresult=-1;Randomrand=newRandom();result=rand.Next(50,150);returnresult;}

//讀取值privatevoidsetVal(){while(true){intwdNum=getWd();lblTemp.Text=wdNum.ToString();if(wdNum>=28){lblFs.Text="打開(kāi)";}else{lblFs.Text="關(guān)閉";}intphotoNum=getPhoto();lblPhoto.Text=photoNum.ToString();if(photoNum>=100){lblRgb.Text="打開(kāi)";}else{lblRgb.Text="關(guān)閉";}Thread.Sleep(5000);}}線程是操作系統(tǒng)運(yùn)算調(diào)度的最小單位,多線程協(xié)作能提高程序執(zhí)行效率。線程有多種狀態(tài),線程通過(guò)start()啟動(dòng)執(zhí)行,通過(guò)sleep()進(jìn)入睡眠狀態(tài)。子線程訪問(wèn)主線程控件狀態(tài)可能拋出異常信息。任務(wù)1

線程實(shí)現(xiàn)頁(yè)面刷新任務(wù)小結(jié)任務(wù)描述在任務(wù)1中通過(guò)設(shè)置Control.CheckForIllegalCrossThreadCalls=false;避免了系統(tǒng)對(duì)子線程訪問(wèn)主線程更新UI控件的安全檢查,這樣可以避免程序因?yàn)樗⑿陆缑娉霈F(xiàn)的“假死”現(xiàn)象,但在實(shí)際應(yīng)用中,因?yàn)槎嗑€程可能同時(shí)訪問(wèn)主線程同一控件,在線程數(shù)不多的情況下可能看不出問(wèn)題,但在線程數(shù)量增多及訪問(wèn)UI控件頻率增大的情況下可能導(dǎo)致數(shù)據(jù)錯(cuò)誤,因此當(dāng)子線程訪問(wèn)主線程申請(qǐng)控制UI控件后,最好有一個(gè)應(yīng)答的過(guò)程,在訪問(wèn)前申請(qǐng),在訪問(wèn)后告之,任務(wù)2通過(guò)委托及control.Invoke和Control.BeginInvoke實(shí)現(xiàn)UI控件的刷新實(shí)現(xiàn)項(xiàng)目功能。任務(wù)2

委托實(shí)現(xiàn)頁(yè)面刷新1.委托任務(wù)2委托實(shí)現(xiàn)頁(yè)面刷新知識(shí)引入委托是.NETFramework引入的概念,它是面向?qū)ο蟮模愃朴贑語(yǔ)言中的函數(shù)指針,通過(guò)委托可以調(diào)用C#中的方法,委托是一種特殊的對(duì)象類型,定義一個(gè)委托可以同時(shí)引用多個(gè)方法,委托只是定義了這一類方法的參數(shù)類型和參數(shù)個(gè)數(shù),不指定具體的方式功能,在實(shí)例化委托時(shí)通過(guò)方法參數(shù)具體到特定的方法,通過(guò)調(diào)用委托實(shí)現(xiàn)方法的調(diào)用執(zhí)行。使用委托方法如下:

定義委托

實(shí)例化委托

調(diào)用委托在C#中使得delegate關(guān)鍵字定義委托,語(yǔ)法為:[訪問(wèn)修飾符]deletate返回值類型

委托名([參數(shù)列表]);如publicdeletateintGetData(inta,intb);1.委托任務(wù)2委托實(shí)現(xiàn)頁(yè)面刷新知識(shí)引入【例5-5】委托的定義

usingSystem;usingSystem.Collections.Generic;usingSystem.Text;namespaceDemo5_4{classProgram{//定義委托publicdelegateintGetData(intn);publicstaticintGetSum(intn){intsum=0;for(inti=1;i<=n;i++){sum+=i;}returnsum;

}publicstaticintGetFac(intn){intfac=1;for(inti=1;i<=n;i++){fac*=i;}returnfac;}staticvoidMain(string[]args){GetDatagetsum=newGetData(GetSum);GetDatagetfac=newGetData(GetFac);Console.WriteLine(getsum(5));Console.WriteLine(getfac(5));}}}1.委托任務(wù)2委托實(shí)現(xiàn)頁(yè)面刷新知識(shí)引入【例5-6】指向?qū)嵗椒ǖ奈惺褂?/p>

publicdelegatevoidshow();classDemo5{publicvoidmsgShow(){Console.WriteLine("考試時(shí)間到");}}classProgram{staticvoidMain(string[]args){showmsgshow=newshow(newDemo5().msgShow);msgshow();}}1.委托任務(wù)2委托實(shí)現(xiàn)頁(yè)面刷新知識(shí)引入【例5-7】匿名委托的使用

publicdelegatevoidshow();classProgram{staticvoidMain(string[]args){showmsgshow=delegate(){Console.WriteLine("下課了");};msgshow();}

}2.Invoke()和BeginInvoke()任務(wù)2委托實(shí)現(xiàn)頁(yè)面刷新知識(shí)引入Control.Invoke(Delegate):在擁有此控件的基礎(chǔ)窗口句柄的線程上執(zhí)行指定的委托。Control.BeginInvoke(Delegate):在創(chuàng)建控件的基礎(chǔ)句柄所在線程上異步執(zhí)行指定委托。的windows窗體應(yīng)用程序中,子線程更新主線程創(chuàng)建UI控件,經(jīng)常通過(guò)后臺(tái)線程實(shí)現(xiàn)調(diào)用Invoke()和Begininvoke()方法與主線程發(fā)送消息。2.Invoke()和BeginInvoke()任務(wù)2委托實(shí)現(xiàn)頁(yè)面刷新知識(shí)引入【例5-8】下面使用委托及Invoke()方法實(shí)現(xiàn)主線程UI控件刷新,程序運(yùn)行如圖所示:點(diǎn)擊按鈕“button1”后,上面的標(biāo)簽在“紅色”變?yōu)椤八{(lán)色”,并且每隔2秒在兩種顏色之間進(jìn)行切換。2.Invoke()和BeginInvoke()任務(wù)2委托實(shí)現(xiàn)頁(yè)面刷新知識(shí)引入【例5-8】publicdelegatevoidUpdateUI();publicForm2(){InitializeComponent();}privatevoidsetText(){while(true){if(InvokeRequired){if(label1.Text.Equals("紅色")){this.Invoke(newUpdateUI(delegate(){label1.Text="藍(lán)色";}));}

else{this.Invoke(newUpdateUI(delegate(){label1.Text="紅色";}));}Thread.Sleep(2000);}}}privatevoidbutton1_Click(objectsender,EventArgse){UpdateUIupdateUi=newUpdateUI(setText);Threadt=newThread(newThreadStart(updateUi));t.IsBackground=true;t.Start();}publicpartialclassForm1:Form{publicdelegatevoidUpdateUI();publicForm1(){InitializeComponent();}privatevoidForm1_Load(objectsender,EventArgse){Threadt=newThread(newThreadStart(setVal));t.IsBackground=true;t.Start();}任務(wù)2委托實(shí)現(xiàn)頁(yè)面刷新任務(wù)實(shí)現(xiàn)//隨機(jī)生成溫度privateintgetWd(){intresult=-1;Randomrand=newRandom();result=rand.Next(20,35);returnresult;}//隨機(jī)生成光敏privateintgetPhoto(){intresult=-1;Randomrand=newRandom();result=rand.Next(50,150);returnresult;}//讀取值privatevoidsetVal(){while(true){if(InvokeRequired){intwdNum=getWd();intphotoNum=getPhoto();this.Invoke(newUpdateUI(delegate(){lblTemp.Text=wdNum.ToString();任務(wù)2委托實(shí)現(xiàn)頁(yè)面刷新任務(wù)實(shí)現(xiàn)if(wdNum>=28){lblFs.Text="打開(kāi)";}else{lblFs.Text="關(guān)閉";}lblPhoto.Text=photoNum.ToString();if(photoNum>=100){lblRgb.Text="打開(kāi)";}else{lblRgb.Text="關(guān)閉";}}));Thread.Sleep(3000);}}}}委托使關(guān)鍵字delegate進(jìn)行定義。委托類似于C語(yǔ)言的函數(shù)指針,委托在實(shí)例化時(shí)的參數(shù)為方法名。子線程通過(guò)Invoke()和Begininvoke()方法與主線程發(fā)送消息。任務(wù)小結(jié)任務(wù)2委托實(shí)現(xiàn)頁(yè)面刷新C#作為面向?qū)ο蟮某绦蛟O(shè)計(jì),任何事物都是對(duì)象,UI界面中的控件都作為一個(gè)單獨(dú)的對(duì)象存在,對(duì)象與對(duì)象之間通過(guò)發(fā)送消息進(jìn)行通信,接受消息的對(duì)象可以根據(jù)信息引發(fā)不同的動(dòng)作,在C#中通過(guò)事件機(jī)制發(fā)送消息,通過(guò)事件機(jī)制可以保證UI控件的更新必須在滿足一條件下執(zhí)行,只有訂閱了特定事件的控件在該事件發(fā)生后才引發(fā)事件代碼的執(zhí)行,如果事件沒(méi)有發(fā)生或控件沒(méi)有訂閱事件,則不執(zhí)行刷新代碼,這樣極大地提高了程序的執(zhí)行效率。比如任務(wù)中的溫度監(jiān)測(cè)控制只有在溫度傳感器在線時(shí)再執(zhí)行頁(yè)面刷新動(dòng)作,光照監(jiān)測(cè)控制只有在光照傳感器工作時(shí)再執(zhí)行頁(yè)面刷新動(dòng)作,避免了資源浪費(fèi)。任務(wù)描述任務(wù)3事件引發(fā)頁(yè)面刷新C#中的事件通過(guò)委托來(lái)實(shí)現(xiàn),事件允許一個(gè)對(duì)象向另一個(gè)對(duì)象通知消息,發(fā)送消息的對(duì)象稱為事件源,被通知的對(duì)象要求事先訂閱事件,只有訂閱了事件的對(duì)象才能收到消息,C#中的事件處理步驟如下:定義事件訂閱事件事件發(fā)生時(shí)通知訂閱者事件的定義:[訪問(wèn)修飾符]event委托名

事件名;因此,事件在定義前首先要定義委托,然后再根據(jù)委托定義事件,例:publicdelegatevoidsetUiHandler();publiceventsetUiHandlereventsetUiHandler;知識(shí)引入任務(wù)3事件引發(fā)頁(yè)面刷新1.事件1.事件知識(shí)引入任務(wù)3事件引發(fā)頁(yè)面刷新訂閱事件:訂閱事件使用運(yùn)算符“+=”,一個(gè)事件可以被多個(gè)對(duì)象訂閱,訂閱者可能通過(guò)“-=”取消已訂閱的事件,例:eventsetUiHandler+=newsetUiHandler(toolWd.getWd);eventsetUiHandler+=newsetUiHandler(toolPhoto.getPhoto);引發(fā)事件:if(eventsetUiHandler!=null){eventsetUiHandler();}當(dāng)沒(méi)有對(duì)象訂閱eventsetUiHandler時(shí),則eventsetUiHandler的值為null,否則訂閱者將激發(fā)事件并執(zhí)行事件代碼。1.事件知識(shí)引入任務(wù)3事件引發(fā)頁(yè)面刷新【例5-9】事件的定義

publicdelegatevoidLaunchHandler();//定義委托publicclassLaunch{publiceventLaunchHandlerEventLaunchHandler;//定義事件publicvoidBeginLanuch(){Console.WriteLine("衛(wèi)星發(fā)射倒計(jì)時(shí)30分鐘,各組進(jìn)入準(zhǔn)備");if(EventLaunchHandler!=null){EventLaunchHandler();}}

}1.事件知識(shí)引入任務(wù)3事件引發(fā)頁(yè)面刷新【例5-9】事件的定義

publicclassPrepareCommand{stringpid;publicPrepareCommand(){}publicPrepareCommand(stringpid){this.pid=pid;}publicvoidcommand(){Console.WriteLine("指揮組"+pid+"進(jìn)入30分鐘準(zhǔn)備狀態(tài),正常");}}publicclassPrepareControl{stringpid;publicPrepareControl(){}publicPrepareControl(stringpid){this.pid=pid;}publicvoidcontrol(){Console.WriteLine("控制組"+pid+"進(jìn)入30分鐘準(zhǔn)備狀態(tài),正常");}}1.事件知識(shí)引入任務(wù)3事件引發(fā)頁(yè)面刷新【例5-9】事件的定義

publicclassPrepareRta{stringpid;publicPrepareRta(){}publicPrepareRta(stringpid){this.pid=pid;}publicvoidrta(){Console.WriteLine("監(jiān)控組"+pid+"進(jìn)入30分鐘準(zhǔn)備狀態(tài),正常");}}classProgram{staticvoidMain(string[]args){Launchlaunch=newLaunch();PrepareCommandp1=newPrepareCommand("A001");PrepareControlp2=newPrepareControl("B001");PrepareRtap3=newPrepareRta("C001");//訂閱事件launch.EventLaunchHandler+=newLaunchHandler(mand);launch.EventLaunchHandler+=newLaunchHandler(p2.control);launch.EventLaunchHandler+=newLaunchHandler(p3.rta);launch.BeginLanuch();

}}2.參數(shù)事件知識(shí)引入任務(wù)3事件引發(fā)頁(yè)面刷新EventArgs類用作表示事件數(shù)據(jù)的所有類的基類。例如,System.AssemblyLoadEventArgs類派生自EventArgs和用來(lái)保存程序集加載事件的數(shù)據(jù)。若要?jiǎng)?chuàng)建一個(gè)自定義事件數(shù)據(jù)類,可創(chuàng)建EventArgs子類,并提供用于存儲(chǔ)所需的數(shù)據(jù)的屬性。通常自定義事件數(shù)據(jù)類的名稱應(yīng)以EventArgs結(jié)尾2.參數(shù)事件知識(shí)引入任務(wù)3事件引發(fā)頁(yè)面刷新【例5-10】參數(shù)事件的使用

publicdelegatevoidEventMenuHandler(objectsource,TestEventArgse);publicclassTestEventArgs:EventArgs{publicintmenu{get;set;}publicTestEventArgs(intmenu){this.menu=menu;}

}classMenu{publiceventEventMenuHandlerEventMenu;privateintmenu;publicintMenuSelect{get{returnmenu;}set{if(EventMenu!=null){TestEventArgsargs=newTestEventArgs(value);EventMenu(this,args);this.menu=args.menu;}}}}2.參數(shù)事件知識(shí)引入任務(wù)3事件引發(fā)頁(yè)面刷新【例5-10】參數(shù)事件的使用

classProgram{staticvoidMain(string[]args){Menumenu1=newMenu();menu1.EventMenu+=newEventMenuHandler(menuTest);menu1.MenuSelect=1;menu1.MenuSelect=4;}publicstaticvoidmenuTest(objectsource,TestEventArgse){if(e.menu==4){Console.WriteLine("系統(tǒng)退出:---"+DateTime.Now);Environment.Exit(0);}else{Console.WriteLine("歡迎進(jìn)入系統(tǒng),您選擇的菜單為:"+e.menu);}}}publicpartialclassForm1:Form{publicdelegatevoidUpdateUI();publiceventUpdateUIEventUpdate;publicForm1(){InitializeComponent();}privatevoidForm1_Load(objectsender,EventArgse){EventUpdate+=newUpdateUI(setVal);if(EventUpdate!=null){Threadt=newThread(newThreadStart(EventUpdate));t.IsBackground=true;t.Start();}}任務(wù)實(shí)現(xiàn)任務(wù)3事件引發(fā)頁(yè)面刷新//控件刷新privatevoidsetVal(){while(true){if(InvokeRequired){intwdNum=getWd();intphotoNum=getPhoto(); //泛型委托Actionthis.Invoke(newAction(delegate(){lblTemp.Text=wdNum.ToString();if(wdNum>=28){lblFs.Text="打開(kāi)";}else{lblFs.Text="關(guān)閉";}lblPhoto.Text=photoNum.ToString();if(photoNum>=100){lblRgb.Text="打開(kāi)";}else{lblRgb.Text="關(guān)閉";}}));Thread.Sleep(3000);

}}}}任務(wù)實(shí)現(xiàn)任務(wù)3事件引發(fā)頁(yè)面刷新//隨機(jī)生成溫度privateintgetWd(){intresult=-1;Randomrand=newRandom();result=rand.Next(20,35);returnresult;}//隨機(jī)生成光敏privateintgetPhoto(){intresult=-1;Randomrand=newRandom();result=rand.Next(50,150);returnresult;}定義事件前首先要定義委托。訂閱者訂閱事件后引發(fā)事件處理程序的執(zhí)行。任務(wù)小結(jié)任務(wù)3事件引發(fā)頁(yè)面刷新C#支持多線程技術(shù),通過(guò)多線程編程能提高程序執(zhí)行效率。委托包含對(duì)方法的引用,通過(guò)委托定義可以將委托指向多個(gè)方法,可以委托的實(shí)例化使委托調(diào)用某個(gè)具體方法。事件允許一個(gè)對(duì)象將消息通知其他的對(duì)象,發(fā)送消息的對(duì)象稱為事件源。項(xiàng)目總結(jié)ATM機(jī)自動(dòng)報(bào)警系統(tǒng)任務(wù)1:服務(wù)器端功能實(shí)現(xiàn)任務(wù)2:客戶端功能實(shí)現(xiàn)項(xiàng)目六ATM機(jī)自動(dòng)報(bào)警系統(tǒng)模擬了ATM機(jī)終端用戶在發(fā)生突發(fā)事件后通過(guò)“報(bào)警”按鈕向監(jiān)控服務(wù)端發(fā)送信息后,服務(wù)端通過(guò)接收信息進(jìn)行相應(yīng)處理的系統(tǒng)解決方案。在項(xiàng)目中,ATM終端用戶主要模擬“報(bào)警”、“撤消報(bào)警”兩個(gè)操作,服務(wù)器端主要包括模擬“出警”、“撤消警告”兩個(gè)操作。計(jì)算機(jī)網(wǎng)絡(luò)將現(xiàn)實(shí)生活中的不同終端連接到一起,網(wǎng)絡(luò)中的計(jì)算機(jī)可以通過(guò)IP地址和端口號(hào)進(jìn)行數(shù)據(jù)的通信,ATM機(jī)自動(dòng)報(bào)警系統(tǒng)是一種點(diǎn)對(duì)點(diǎn)的通信方式,C#中的Socket網(wǎng)絡(luò)編程基于TCP/IP協(xié)議,為實(shí)現(xiàn)C/S結(jié)構(gòu)的網(wǎng)絡(luò)通信提供了解決方案。項(xiàng)目引入理解TCP/IP、IP地址、端口、套接字的概念理解C/S網(wǎng)絡(luò)編程概念掌握Socket編程方法

學(xué)習(xí)目標(biāo)服務(wù)器端:首先運(yùn)行ATM服務(wù)器端監(jiān)控程序,運(yùn)行效果如圖6-1所示:項(xiàng)目描述點(diǎn)擊開(kāi)始監(jiān)控,服務(wù)器對(duì)端口進(jìn)行監(jiān)控,文本框中顯示日志信息,此時(shí)“出警”和“銷警”按鈕不可用。如圖6-2所示:當(dāng)有客戶端點(diǎn)擊“報(bào)警”按鈕,文本框顯示“報(bào)警信息”,對(duì)應(yīng)的標(biāo)簽顯示為“紅色”,同時(shí)“出警”和“銷警”按鈕恢復(fù)為可用狀態(tài),效果如圖6-3所示:項(xiàng)目描述點(diǎn)擊“出警”按鈕,文本框顯示“出警信息”,對(duì)應(yīng)的標(biāo)簽顯示為“藍(lán)色”,效果如圖6-4所示:點(diǎn)擊“銷警”按鈕,文本框顯示“銷警信息”,對(duì)應(yīng)的標(biāo)簽顯示為“灰色”,效果如圖6-5所示:項(xiàng)目描述客戶端:客戶端運(yùn)行后,自動(dòng)連接服務(wù)器端,主界面效果如圖6-6所示:點(diǎn)擊“報(bào)警”按鈕,標(biāo)簽變?yōu)椤凹t色”,文本框顯示“報(bào)警”日志信息,效果如圖6-7所示:項(xiàng)目描述如果收到服務(wù)器端“出警”信息,標(biāo)簽變?yōu)椤八{(lán)色”,文本框顯示“出警”日志信息,效果如圖6-8所示:點(diǎn)擊“銷警”按鈕,文本框顯示“請(qǐng)求銷警”日志信息,效果如圖6-9所示:項(xiàng)目描述如果收到服務(wù)器端“銷警”信息,標(biāo)簽變?yōu)椤盎疑?,文本框顯示“銷警”日志信息,效果如圖6-10所示:任務(wù)1:服務(wù)器端功能實(shí)現(xiàn)任務(wù)2:客戶端功能實(shí)現(xiàn)工作任務(wù)任務(wù)描述服務(wù)器端創(chuàng)建連接后,要實(shí)現(xiàn)客戶端的信息監(jiān)控,當(dāng)客戶端發(fā)送“報(bào)警”信息后,服務(wù)器端接收到信息要進(jìn)行相應(yīng)的“出警”處理,當(dāng)客戶端請(qǐng)求“撤消報(bào)警”后,服務(wù)器端接收到信息后要進(jìn)行相應(yīng)的“撤消警告”處理。任務(wù)1服務(wù)器端功能實(shí)現(xiàn)1.IP地址

Internet通過(guò)網(wǎng)絡(luò)將計(jì)算機(jī)連接在一起,每一臺(tái)計(jì)算機(jī)都有自己的一個(gè)地址,信息在網(wǎng)絡(luò)中傳輸遵循網(wǎng)絡(luò)傳輸協(xié)議TCP/IP協(xié)議,按照TCP/IP協(xié)議,IP地址由一組二進(jìn)制數(shù)組成,IP地址包括IPV4和IPV6,分別由32位和64位二進(jìn)制數(shù)組成,目前使用較多的為IPV4地址,為方便使用,IP地址經(jīng)常使用十進(jìn)制數(shù)來(lái)描述,每8位二進(jìn)制數(shù)轉(zhuǎn)換成一個(gè)十進(jìn)制數(shù),中間用“.”分隔。如:26。C#中System.Net命名空間為網(wǎng)絡(luò)編程提供支持類,System.Net.Sockets命名空間為Socket編程提供支持類。

IPAddress類

功能:提供主機(jī)的IP地址及相關(guān)信息。

IPHostEntry類

功能:提供主機(jī)的IP地址、主機(jī)名及別名。主要屬性:AddressList:返回IPAddress[],獲取或設(shè)置與主機(jī)關(guān)聯(lián)的IP地址列表。HostName:返回string[],獲取或設(shè)置主機(jī)的DNS名稱。知識(shí)引入任務(wù)1服務(wù)器端功能實(shí)現(xiàn)1.IP地址

IPEndPoint類功能:將網(wǎng)絡(luò)端點(diǎn)表示為IP地址和端口號(hào)。通過(guò)IP地址和端口號(hào)的組合,構(gòu)造主機(jī)的連接點(diǎn)。主要屬性:Address:獲取或設(shè)置終結(jié)點(diǎn)IP地址。AddressFamily:獲取網(wǎng)絡(luò)協(xié)議(IP)地址族。AddressFamily.InterNetwork表示此IP為IPv4,AddressFamily.InterNetworkV6表示此地址為IPv6類型。Port:獲取或設(shè)置終結(jié)點(diǎn)的端口號(hào)。Dns類功能:提供簡(jiǎn)單的域名解析功能。主要屬性:GetHostName:獲取本地計(jì)算機(jī)的主機(jī)名。GetHostAddresses:返回指定主機(jī)的Internet協(xié)議(IP)地址。GetHostEntry:將主機(jī)名或IP地址解析為IPHostEntry實(shí)例。知識(shí)引入任務(wù)1服務(wù)器端功能實(shí)現(xiàn)1.IP地址

【例6-1】輸出本機(jī)IP地址及主機(jī)名。新建控制臺(tái)項(xiàng)目IPGet,編寫(xiě)代碼如下:namespaceIPGet{classProgram{staticvoidMain(string[]args){stringhostName=Dns.GetHostName();IPHostEntrylocalhost=Dns.GetHostEntry(hostName);stringip="";for(inti=0;i<localhost.AddressList.Length;i++){if(localhost.AddressList[i].AddressFamily==AddressFamily.InterNetwork){ip=localhost.AddressList[i].ToString();}}Console.WriteLine("hostName:"+hostName);Console.WriteLine("localIp:"+ip);}}}知識(shí)引入任務(wù)1服務(wù)器端功能實(shí)現(xiàn)2.端口

知識(shí)引入任務(wù)1服務(wù)器端功能實(shí)現(xiàn)

在網(wǎng)絡(luò)連接中,端口分為物理端口和邏輯端口,物理端口指計(jì)算機(jī)硬件的I/O端口,邏輯端口指邏輯意義上用于區(qū)分服務(wù)的端口,如TCP/IP協(xié)議中的服務(wù)端口,端口號(hào)的范圍從0到65535。每一個(gè)網(wǎng)絡(luò)連接都需要一個(gè)端口號(hào),一般來(lái)說(shuō),每個(gè)端口都對(duì)應(yīng)著一種應(yīng)用程序。要建立客戶機(jī)與服務(wù)器之間的連接通信,必須選擇一個(gè)端口進(jìn)行連接,端口號(hào)0-1023是標(biāo)準(zhǔn)的Internet協(xié)議保留端口,用戶創(chuàng)建程序自定義端口號(hào)范圍一般為8000-16000。

3.Socket套接字

知識(shí)引入任務(wù)1服務(wù)器端功能實(shí)現(xiàn)Socket是基于TCP/IP的編程接口,是種網(wǎng)絡(luò)通信機(jī)制,socket的英文原義是“孔”或“插座”。作為進(jìn)程通信機(jī)制,通常也稱作“套接字”,用于描述IP地址和端口。Socket是基于連接的通信,在通信開(kāi)始前通信雙方通過(guò)確定身份(IP地址和端口)建立連接通道,然后通過(guò)連接通道傳送信息。通信結(jié)束后關(guān)閉連接。Socket類構(gòu)造方法:publicSocket(AddressFamilyaddressFamily,SocketTypesocketType,ProtocolTypeprotocolType)addressFamily:指定Socket使用的尋址方案socketType:指定Socket的類型protocolType:指定Socket使用的協(xié)議例:SocketSocketWatch=newSocket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);實(shí)例方法:Socket.Send:從數(shù)據(jù)中的指示位置開(kāi)始將數(shù)據(jù)發(fā)送到連接的SocketSocket.Receive:將數(shù)據(jù)從連接的Socket接收到接收緩沖區(qū)的特定位置Socket.Bind:使Socket與一個(gè)本地終結(jié)點(diǎn)相關(guān)聯(lián)Socket.Listen:將Socket置于偵聽(tīng)狀態(tài)Socket.Accept:創(chuàng)建新的Socket以處理傳入的連接請(qǐng)求Socket.Close:強(qiáng)制Socket連接關(guān)閉

4Socket網(wǎng)絡(luò)編程服務(wù)器端編程步驟

知識(shí)引入任務(wù)1服務(wù)器端功能實(shí)現(xiàn)(1)創(chuàng)建用于監(jiān)聽(tīng)連接的Socket對(duì)象(2)用指定的端口號(hào)和服務(wù)器的ip建立一個(gè)EndPoint對(duì)象(3)Bind()方法綁定EndPoint(4)Listen()方法開(kāi)始監(jiān)聽(tīng)(5)有客戶端連接,Accept()方法創(chuàng)建一個(gè)新的用于和客戶端進(jìn)行通信的socket實(shí)例(6)通信(7)通信結(jié)束關(guān)閉socket。

【例6-2】編寫(xiě)服務(wù)端程序,建立指定端口的連接,監(jiān)聽(tīng)連接的客戶端發(fā)送的信息。程序主界面如圖所示:知識(shí)引入任務(wù)1服務(wù)器端功能實(shí)現(xiàn)【例6-2】新建windows窗體應(yīng)用程序,添加控件并設(shè)置屬性如表所示:知識(shí)引入任務(wù)1服務(wù)器端功能實(shí)現(xiàn)控件屬性值Form1TextSocket服務(wù)器Form1Size600,400Lable1Text服務(wù)器端口TextBox1Text5678TextBox1NametxtPortButton1Text開(kāi)始監(jiān)聽(tīng)Button1NamebtnStartTextBox2NametxtLogTextBox2MultilinetrueTextBox3NametxtMsgTextBox3MultilinetrueButton2Text發(fā)送信息Button2NamebtnSend【例6-2】編寫(xiě)窗口事件代碼知識(shí)引入任務(wù)1服務(wù)器端功能實(shí)現(xiàn)privatevoidbtnStart_Click(objectsender,EventArgse){try{SocketSocketWatch=newSocket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);IPAddressip=IPAddress.Any;IPEndPointpoint=newIPEndPoint(ip,Convert.ToInt32(txtPort.Text));SocketWatch.Bind(point);ShowMsg("監(jiān)聽(tīng)成功!"+":"+GetCurrentTime());SocketWatch.Listen(10);ThreadTh=newThread(Listen);Th.IsBackground=true;Th.Start(SocketWatch);}

catch(Exception){ MessageBox.Show("連接失敗!");}}SocketsocketSend;voidListen(objectobj){SocketSocketWatch=objasSocket;while(true){//等待客戶端連接,并創(chuàng)建一個(gè)負(fù)責(zé)通訊的SocketsocketSend=SocketWatch.Accept();ShowMsg(socketSend.RemoteEndPoint.ToString()+"---連接成功!"+":"+GetCurrentTime());ThreadThRecive=newThread(Recive);ThRecive.IsBackground=true;ThRecive.Start(socketSend);}}【例6-2】編寫(xiě)窗口事件代碼知識(shí)引入任務(wù)1服務(wù)器端功能實(shí)現(xiàn)//不斷調(diào)用接收消息的方法voidRecive(objectobj){SocketSocketSend=objasSocket;while(true){try{//創(chuàng)建一個(gè)數(shù)組儲(chǔ)存客戶端發(fā)過(guò)來(lái)的消息byte[]buffer=newbyte[1024*1024*2];//實(shí)際收到的有效字節(jié)數(shù)intr=SocketSend.Receive(buffer);stringstr=Encoding.UTF8.GetString(buffer,0,r);//將buffer轉(zhuǎn)化成字符串形式if(r==0){break;

}ShowMsg(SocketSend.RemoteEndPoint.ToString()+"---"+str+":"+GetCurrentTime());}catch(Exception){MessageBox.Show("連接失?。?);}}}//文本框追加方法voidShowMsg(stringstr){this.txtLog.AppendText(str+"\r\n");}privatevoidForm1_Load(objectsender,EventArgse){//取消對(duì)線程間的錯(cuò)誤檢查Control.CheckForIllegalCrossThreadCalls=false;}privatevoidbtnSend_Click(objectsender,EventArgse){stringstr=this.txtMsg.Text.Trim();byte[]buffer=System.Text.Encoding.UTF8.GetBytes(str);socketSend.Send(buffer);}//獲取當(dāng)前系統(tǒng)時(shí)間的方法

staticDateTimeGetCurrentTime(){DateTimecurrentTime=newDateTime();currentTime=DateTime.Now;returncurrentTime;}任務(wù)1

服務(wù)器端功能實(shí)現(xiàn)任務(wù)實(shí)現(xiàn)新建windows窗體應(yīng)用程序,程序主界面如圖所示:任務(wù)1

服務(wù)器端功能實(shí)現(xiàn)任務(wù)實(shí)現(xiàn)編寫(xiě)窗口事件代碼操作演示Socket網(wǎng)絡(luò)編程需要引用命名空間System.Net.Sockets、System.Net。先運(yùn)行服務(wù)器端程序進(jìn)入監(jiān)控,后運(yùn)行客戶端程序。在Form_Load事件中設(shè)置Control.CheckForIllegalCrossThreadCalls=false;取消對(duì)線程間的錯(cuò)誤檢查。任務(wù)1

服務(wù)器端功能實(shí)現(xiàn)任務(wù)小結(jié)任務(wù)描述進(jìn)入系統(tǒng)后要求輸入用戶名及密碼,用戶名為“admin”和密碼為“123456”,如果用戶名或密碼輸入錯(cuò)誤,則輸出錯(cuò)誤提示信息并累計(jì)錯(cuò)誤次數(shù),如果錯(cuò)誤次數(shù)達(dá)到三次,系統(tǒng)提示“用戶名或密碼輸入錯(cuò)誤已達(dá)三次!系統(tǒng)將自動(dòng)退出!”,系統(tǒng)自動(dòng)退出,如果用戶名及密碼輸入正確,則顯示“歡迎進(jìn)入聯(lián)通手機(jī)充值系統(tǒng)”。任務(wù)2

客戶端功能實(shí)現(xiàn)1.建立服務(wù)器連接Socket.Connect(IPEndPointpoint)方法:創(chuàng)建與指定服務(wù)器IP和端口號(hào)的連接。2.Socket網(wǎng)絡(luò)編程客戶端編程步驟(1)創(chuàng)建用于連接的Socket對(duì)象(2)用指定的端口號(hào)和服務(wù)器的ip建立一個(gè)EndPoint對(duì)象(3)用socket對(duì)象的Connect()方法向服務(wù)器發(fā)出連接請(qǐng)求(4)如果連接成功,就用socket對(duì)象的Send()方法向服務(wù)器發(fā)送信息(5)用socket對(duì)象的Receive()方法接受服務(wù)器發(fā)來(lái)的信息(6)通信結(jié)束關(guān)閉socket。任務(wù)2客戶端功能實(shí)現(xiàn)知識(shí)引入【例6-3】編寫(xiě)客戶端程序,與服務(wù)器建立指定端口的連接,與服務(wù)器端實(shí)現(xiàn)信息的發(fā)送的接收。程序主界面如圖所示:任務(wù)2客戶端功能實(shí)現(xiàn)知識(shí)引入【例6-3】編寫(xiě)窗口事件代碼:任務(wù)2客戶端功能實(shí)現(xiàn)知識(shí)引入SocketsocketSend;privatevoidbtnConnect_Click(objectsender,EventArgse){try{socketSend=newSocket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);IPAddressip=IPAddress.Parse(txtServer.Text);IPEndPointpoint=newIPEndPoint(ip,Convert.ToInt32(txtPort.Text));//獲得要連接的遠(yuǎn)程服務(wù)器應(yīng)用程序的IP地址和端口號(hào)socketSend.Connect(point);

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論