【正文】
1緒論 視頻監(jiān)控是各行業(yè)重點(diǎn)部門(mén)或重要場(chǎng)所進(jìn)行實(shí)時(shí)監(jiān)控的物理基礎(chǔ),管理部門(mén)可通過(guò)它獲得有效數(shù)據(jù)、圖像或聲音信息,對(duì)突發(fā)性異常事件的過(guò)程進(jìn)行及時(shí)的監(jiān)視和記憶,用以提供高效、及時(shí)地指揮和高度、布置警力、處理案件等。本系統(tǒng)采用DirectShow網(wǎng)絡(luò)組播技術(shù)實(shí)現(xiàn)了視頻捕獲、視頻壓縮、網(wǎng)絡(luò)傳輸、視頻解碼和實(shí)時(shí)回放,減小了網(wǎng)絡(luò)帶寬占用,高效的傳輸視頻數(shù)據(jù),獨(dú)立于硬件??蓴U(kuò)展性好。完全利用現(xiàn)有1P數(shù)據(jù)網(wǎng)絡(luò)傳輸數(shù)據(jù).不需要單獨(dú)布線,顯著降低了系統(tǒng)成本,縮短了系統(tǒng)開(kāi)發(fā)周期,并且可以容易的實(shí)現(xiàn)遠(yuǎn)程監(jiān)測(cè)2 Windows服務(wù)一個(gè)Windows服務(wù)程序是在Windows操作系統(tǒng)下能完成特定功能的可執(zhí)行的應(yīng)用程序。Windows服務(wù)程序雖然是可執(zhí)行的,但是它不像一般的可執(zhí)行文件通過(guò)雙擊就能開(kāi)始運(yùn)行了,它必須有特定的啟動(dòng)方式。這些啟動(dòng)方式包括了自動(dòng)啟動(dòng)和手動(dòng)啟動(dòng)兩種。對(duì)于自動(dòng)啟動(dòng)的Windows服務(wù)程序,它們?cè)赪indows啟動(dòng)或是重啟之后用戶(hù)登錄之前就開(kāi)始執(zhí)行了。而對(duì)于手動(dòng)啟動(dòng)的Windows服務(wù)程序,你可以通過(guò)命令行工具的NET START 命令來(lái)啟動(dòng)它,或是通過(guò)控制面板中管理工具下的服務(wù)一項(xiàng)來(lái)啟動(dòng)相應(yīng)的Windows服務(wù)程序。同樣,一個(gè)Windows服務(wù)程序也不能像一般的應(yīng)用程序那樣被終止。因?yàn)閃indows服務(wù)程序一般是沒(méi)有用戶(hù)界面的,所以你也要通過(guò)命令行工具或是下面圖中的工具來(lái)停止它,或是在系統(tǒng)關(guān)閉時(shí)使得Windows服務(wù)程序自動(dòng)停止。因?yàn)閃indows服務(wù)程序沒(méi)有用戶(hù)界面,為了能使一個(gè)Windows服務(wù)程序能夠正常并有效的在系統(tǒng)環(huán)境下工作,程序員必須實(shí)現(xiàn)一系列的方法來(lái)完成其服務(wù)功能。Windows服務(wù)程序的應(yīng)用范圍很廣,典型的Windows服務(wù)程序包含了硬件控制、應(yīng)用程序監(jiān)視、系統(tǒng)級(jí)應(yīng)用、診斷、報(bào)告、Web和文件系統(tǒng)服務(wù)等功能。 添加文件監(jiān)視服務(wù)將生成的服務(wù)名為Webcamservice的服務(wù)添加視頻監(jiān)視功能:216。 首先,在C盤(pán)創(chuàng)建文件夾w216。 將程序生成的debug中的文件復(fù)制到w文件夾216。 在C/windows/,將其復(fù)制到w文件夾216。 啟動(dòng)cmd,打開(kāi)命令提示符窗體鍵入如圖21所示 圖21 添加服務(wù)功能216。 用net start命令啟動(dòng)服務(wù)Webcamservice如圖22所示 圖22啟動(dòng)Webcamservice3項(xiàng)目的設(shè)計(jì)原理 DirectShow技術(shù)采用網(wǎng)絡(luò)攝像機(jī)的遠(yuǎn)程視頻監(jiān)控具有錄像時(shí)間長(zhǎng)、圖像質(zhì)量好、查詢(xún)速度快等優(yōu)點(diǎn),目前應(yīng)用非常廣泛。對(duì)于網(wǎng)絡(luò)攝像機(jī)傳輸?shù)囊曨l數(shù)據(jù),需要專(zhuān)門(mén)的Filter 來(lái)處理并在DirectShow 的框架下或回放,或保存。監(jiān)控服務(wù)器通過(guò)Internet/Intranet 輪詢(xún)網(wǎng)絡(luò)攝像機(jī)獲取視頻。本文以視頻數(shù)據(jù)接收Filter 的設(shè)計(jì)過(guò)程介紹基于DirectShow 的視頻數(shù)據(jù)流的傳輸以及通過(guò)自定義的通訊協(xié)議的數(shù)據(jù)解析過(guò)程和Filter 程序設(shè)計(jì)與實(shí)現(xiàn)過(guò)程。DirectShow[1]是微軟公司在ActiveMovie 和Video for Windows 的基礎(chǔ)上推出的基于COM 的流媒體處理的開(kāi)發(fā)包,與DirectX 開(kāi)發(fā)包一起發(fā)布。DirectShow 為多媒體流的捕捉和回放以及二次開(kāi)發(fā)提供了強(qiáng)有力的支持。運(yùn)用DirectShow,可以很方便地從支持WDM 驅(qū)動(dòng)模型的采集卡上采集數(shù)據(jù),并且調(diào)用其API 函數(shù)進(jìn)行后期處理。它廣泛地支持各種媒體格式,包括Asf,Mpeg,Avi,Dv,Mp3,Wave等等,使得多媒體數(shù)據(jù)的回放變得輕而易舉。DirectShow 是一個(gè)開(kāi)放的框架,因此只要有合適的Filter 來(lái)分析和解碼,可以支持任何格式。 TCP/IP協(xié)議在TCP/IP協(xié)議組分兩種協(xié)議:網(wǎng)絡(luò)層的協(xié)議,應(yīng)用層的協(xié)議216。 網(wǎng)絡(luò)層協(xié)議 網(wǎng)絡(luò)層協(xié)議管理離散的計(jì)算機(jī)間的數(shù)據(jù)傳輸。這些協(xié)議是在系統(tǒng)表層以下工作的。比如,IP協(xié)議為用戶(hù)和遠(yuǎn)程計(jì)算機(jī)提供了信息包的傳輸方法。它是在許多信息的基礎(chǔ)上工作的,好比說(shuō)是機(jī)器的IP地址。在機(jī)器IP地址和其它信息的基礎(chǔ)上,IP確保信息包能正確地到達(dá)目的機(jī)器。通過(guò)這一過(guò)程,IP和其它網(wǎng)絡(luò)層的協(xié)議共同用于數(shù)據(jù)傳輸。如果沒(méi)有網(wǎng)絡(luò)工具,用戶(hù)就看不到在系統(tǒng)里工作的IP。216。 應(yīng)用層協(xié)議相反地,應(yīng)用層協(xié)議用戶(hù)是可以看得到的。比如,文件傳輸協(xié)議(FTP)用戶(hù)是看得到的。用戶(hù)為了傳輸一個(gè)文件請(qǐng)求一個(gè)和其它計(jì)算機(jī)的連接,連接建立后,就開(kāi)始傳輸文件。在傳輸時(shí),用戶(hù)和遠(yuǎn)程計(jì)算機(jī)的交換的一部分是能看到的。216。 IPIP層接收由更低層(網(wǎng)絡(luò)接口層例如以太網(wǎng)設(shè)備驅(qū)動(dòng)程序)發(fā)來(lái)的數(shù)據(jù)包,并把該數(shù)據(jù)包發(fā)送到更高層TCP或UDP層;相反,IP層也把從TCP或UDP層接收來(lái)的數(shù)據(jù)包傳送到更低層。IP數(shù)據(jù)包是不可靠的,因?yàn)镮P并沒(méi)有做任何事情來(lái)確認(rèn)數(shù)據(jù)包是按順序發(fā)送的或者沒(méi)有被破壞。IP數(shù)據(jù)包中含有發(fā)送它的主機(jī)的地址(源地址)和接收它的主機(jī)的地址(目的地址)。高層的TCP和UDP服務(wù)在接收數(shù)據(jù)包時(shí),通常假設(shè)包中的源地址是有效的。也可以這樣說(shuō),IP地址形成了許多服務(wù)的認(rèn)證基礎(chǔ),這些服務(wù)相信數(shù)據(jù)包是從一個(gè)有效的主機(jī)發(fā)送來(lái)的。216。 TCP如果IP數(shù)據(jù)包中有已經(jīng)封好的TCP數(shù)據(jù)包,那么IP將把它們向上傳送到TCP層。TCP將包排序并進(jìn)行錯(cuò)誤檢查,同時(shí)實(shí)現(xiàn)虛電路間的連接。TCP數(shù)據(jù)包中包括序號(hào)和確認(rèn),所以未按照順序收到的包可以被排序,而損壞的包可以被重傳。TCP將它的信息送到更高層的應(yīng)用程序,例如Telnet的服務(wù)程序和客戶(hù)程序。應(yīng)用程序輪流將信息送回TCP層,TCP層便將它們向下傳送到IP層,設(shè)備驅(qū)動(dòng)程序和物理介質(zhì),最后到接收方。 C/S架構(gòu)服務(wù)器客戶(hù)端客戶(hù)端 . . .在網(wǎng)絡(luò)連接模式中除對(duì)等網(wǎng)外,還有另一種形式的網(wǎng)絡(luò),即客戶(hù)機(jī)/服務(wù)器網(wǎng),Client/Server。在客戶(hù)機(jī)/服務(wù)器網(wǎng)絡(luò)中,服務(wù)器是網(wǎng)絡(luò)的核心,而客戶(hù)機(jī)是網(wǎng)絡(luò)的基礎(chǔ),客戶(hù)機(jī)依靠服務(wù)器獲得所需要的網(wǎng)絡(luò)資源,而服務(wù)器為客戶(hù)機(jī)提供網(wǎng)絡(luò)必須的資源。 圖31 c/s結(jié)構(gòu)4程序流程圖及設(shè)計(jì)本系統(tǒng)采用面向連接的客戶(hù)/服務(wù)模型,服務(wù)器必須首先啟動(dòng),否則客戶(hù)進(jìn)程的Connect()系統(tǒng)調(diào)用將返回錯(cuò)誤代碼表示連接失敗。無(wú)連接的服務(wù)進(jìn)程也必須首先啟動(dòng)以指定本地的套接字地址否則客戶(hù)進(jìn)程的數(shù)據(jù)服務(wù)請(qǐng)求傳送不到服務(wù)器進(jìn)程。面向連接的c/s時(shí)序圖如圖41所示Accept()Recv()Send()Close()Listen()Bind()Socket()服務(wù)器發(fā)送數(shù)據(jù)確認(rèn)發(fā)送數(shù)據(jù)請(qǐng)求建立連接Recv()Close()Send()Connect()Socket()客戶(hù) 圖41 程序時(shí)序圖系統(tǒng)由服務(wù)器終端采集傳輸系統(tǒng)和客戶(hù)端接收系統(tǒng)兩部分組,系統(tǒng)構(gòu)架如圖42所示攝像頭采集卡服務(wù)器服務(wù)程序網(wǎng)絡(luò)傳輸模塊網(wǎng)絡(luò)接收模塊客戶(hù)端程序解碼顯示視頻流控制指令視頻流控制指令 圖42 系統(tǒng)架構(gòu)服務(wù)器端程序目標(biāo):服務(wù)器服務(wù)器端服務(wù)程序進(jìn)行數(shù)據(jù)采集(捕捉攝像頭捕獲數(shù)據(jù)),提供IP端口實(shí)現(xiàn)數(shù)據(jù)流的傳輸??蛻?hù)端程序目標(biāo):客戶(hù)端程序通過(guò)IP協(xié)議與服務(wù)器端通信,接收并回放服務(wù)器端采集的視頻數(shù)據(jù)流。Socket類(lèi):socket之間的連接可以分為三種類(lèi)型:客戶(hù)端連接,監(jiān)聽(tīng)連接以及服務(wù)器端連接。 客戶(hù)端連接是指由客戶(hù)端的socket提出連接請(qǐng)求,要連接的目標(biāo)是服務(wù)器端的socket。為此,客戶(hù)端的socket必須首先描述它要連接的服務(wù)器端socket(主要是指服務(wù)器 端socket的地址和端口號(hào)),然后再定位所要連接的服務(wù)器端socket,找到以后,就向服務(wù)器端 socket請(qǐng)求連接。當(dāng)然,服務(wù)器端的socket此時(shí)未必正好處于準(zhǔn)備好狀態(tài),不過(guò),服務(wù)器端的 socket會(huì)自動(dòng)維護(hù)客戶(hù)請(qǐng)求連接的隊(duì)列,然后在它認(rèn)為合適的時(shí)候向客戶(hù)端socket發(fā)出允許連接 (accept)的信號(hào),這時(shí)客戶(hù)端socket與服務(wù)器端socket的連接就建立了。監(jiān)聽(tīng)連接,服務(wù)器端 socket并不定位具體的客戶(hù)端socket,而是處于等待連接的狀態(tài)。當(dāng)服務(wù)器端socket監(jiān)聽(tīng)到或者說(shuō) 接收到客戶(hù)端socket的連接請(qǐng)求,它就響應(yīng)客戶(hù)端socket的請(qǐng)求建立一個(gè)新的socket句柄并與客戶(hù) 端連接,而服務(wù)器端socket繼續(xù)處于監(jiān)聽(tīng)狀態(tài),還可以接收其它客戶(hù)端socket的連接請(qǐng)求。服務(wù)器端連接,是指當(dāng)服務(wù)器端socket接收到客戶(hù)端socket的連接請(qǐng)求后,就把服務(wù)器端socket的描述發(fā)給客戶(hù)端,一旦客戶(hù)端確認(rèn)了此描述,連接就建立了。在本文中的聊天程序用的就是監(jiān)聽(tīng)連接,即服務(wù)器設(shè)置連接個(gè)數(shù)后進(jìn)行監(jiān)聽(tīng),客戶(hù)端進(jìn)行對(duì)服務(wù)器端的連接,這樣就可以進(jìn)行相互通信了。TcpService類(lèi)namespace TCP{ internal class TcpServer : IDisposable { // This is not the max number of connections you can have, it39。s the number // that can queue up waiting for you to Accept them. If more than MAXCONNECTION // more clients try to connect while you are servicing another, OnConnect is // probably taking too long. const int MAXCONNECTIONS = 3。 region Member variables private ArrayList m_aryClients。 private Socket m_sockListener。 private volatile bool m_bShuttingDown。 private ManualResetEvent ShutDownReady。 endregion // Return an array of the ip addresses assigned to this pc public static IPAddress [] GetAddresses() { IPAddress [] aryLocalAddr = null。 string strHostName = 。 // NOTE: DNS lookups are nice and all but quite time consuming. strHostName = ()。if USING_NET11 IPHostEntry ipEntry = ( strHostName )。else IPHostEntry ipEntry = ( strHostName )。endif aryLocalAddr = 。 // Verify we got an IP address. if( aryLocalAddr == null || 1 ) { throw new Exception( Unable to get local address )。 } return aryLocalAddr。 } public TcpServer(int nPortListen) { _TcpServer(nPortListen, GetAddresses()[0])。 } public TcpServer(int nPortListen, IPAddress ip) { _TcpServer(nPortListen, ip)。 } // Shut down the listener public void Dispose() { // Shutting down is a real PITA. You can39。t close the listener // while there is an outstanding async call active. And you can39。t //