【正文】
設(shè)置的選項(xiàng) /// /summary protected override void OnStart(string[] args) { ThreadStart starter = new ThreadStart(Run)。 /// summary /// The thread will run the job. /// The job is the Method Run() below /// /summary protected Thread thread = null。 15 if ( ) { ()。 } protected override void Dispose( bool disposing ) { if( disposing ) { if (ponents != null) { ()。 } WebCamService 類 : namespace WebCamService { public class WebCamService : ServiceBase { region Required Service Related Methods private ponents = null。 obj = new object()。 public byte [] byBuff。 ()。 ( , 0, , , receiveData, s )。 } } } // Client has sent data, or has disconnected private void OnReceivedData( IAsyncResult ar ) { // Socket was the passed in object SockWrapper s = (SockWrapper)。 // (Re)Setup a callback to be notified of connection requests (new AsyncCallback( OnConnectRequest ) , listener )。 ( s )。 if (bSend) (b, iLength, )。 throw。 ( new IPEndPoint( ip, nPortListen ) )。 ShutDownReady = new ManualResetEvent(false)。 public event TcpConnected Disconnected。 } // Send to all connected clients public void SendToAll(MemoryStream m) { _SendToAll((), (int))。 ()。 } } if (t != null) { // Listen for the async listener to let go. This must be done // outside the crit section since the listener needs to lock it. (3000, false)。 ()。t // cancel the async call. Grr. As a workaround, this routine // makes a connection to the port. The OnConnect routine, recognizing // that we are in shutdown, doesn39。 } public TcpServer(int nPortListen) { _TcpServer(nPortListen, GetAddresses()[0])。 else IPHostEntry ipEntry = ( strHostName )。 endregion // Return an array of the ip addresses assigned to this pc public static IPAddress [] GetAddresses() { IPAddress [] aryLocalAddr = null。 region Member variables private ArrayList m_aryClients。 服務(wù)器端連接,是指當(dāng)服務(wù)器端 socket接收到客戶端 socket的連接 請(qǐng)求后,就把服務(wù)器端 socket 的描述發(fā)給客戶端,一旦客戶端確認(rèn)了此描述,連接就建立了。為此,客戶端的 socket 必須首先描述它要連接的服務(wù)器端socket(主要是指服務(wù)器 端 socket 的地址和端口號(hào) ),然后再定位所要連接的服務(wù)器端 socket,找到以后,就向服務(wù)器端 socket 請(qǐng)求連接。 面向連接的 c/s時(shí)序圖如圖 41所示 服務(wù)器 客戶端 客戶端 . . . 5 圖 41 程序時(shí)序圖 系統(tǒng)由服務(wù)器終端采集傳輸系統(tǒng)和客戶端接收系統(tǒng)兩部分組,系統(tǒng)構(gòu)架如圖 42所示 圖 42 系統(tǒng)架構(gòu) 程序設(shè)計(jì)分析 Accept() Recv() Send() Close() Listen() Bind() Socket() 服務(wù)器 發(fā)送數(shù)據(jù) 確認(rèn)發(fā)送數(shù)據(jù) 請(qǐng)求建立連接 Recv() Close() Send() Connect() Socket() 客戶 攝像頭 采集卡 服務(wù)器服務(wù)程序 網(wǎng)絡(luò)傳輸模塊 網(wǎng)絡(luò)接收模塊 客戶端程序 解碼 顯示 視頻流 控制指令 視頻流 控制指令 6 任務(wù)目標(biāo) 服務(wù)器端程序目標(biāo):服務(wù)器服務(wù)器端服務(wù)程序進(jìn)行數(shù)據(jù)采集(捕捉攝像頭捕獲數(shù)據(jù)),提供IP端口實(shí)現(xiàn)數(shù)據(jù)流的傳輸。 C/S 架構(gòu) 在網(wǎng)絡(luò)連接模式 中除對(duì)等網(wǎng)外 ,還有另一種形式的網(wǎng)絡(luò),即客戶機(jī) /服務(wù)器網(wǎng),Client/Server。 TCP將包排序并進(jìn)行錯(cuò)誤檢查,同時(shí)實(shí)現(xiàn)虛電路間的連接。 IP 數(shù)據(jù)包中含有發(fā)送它的主機(jī)的地址(源地址)和接收它的主機(jī)的地址 4 (目的地址)。用戶為了傳輸一個(gè)文件請(qǐng)求一個(gè)和其它計(jì)算機(jī)的連接,連接 建立后,就開始傳輸文件。通過這一過程, IP 和其它網(wǎng)絡(luò)層的協(xié)議共同用于數(shù)據(jù)傳輸。這些協(xié)議是在系統(tǒng)表層以下工作的。 運(yùn)用 DirectShow,可以很方便地從支持 WDM 驅(qū)動(dòng)模型的采集卡上采集數(shù)據(jù),并且調(diào)用其 API 函數(shù)進(jìn)行后期處理。監(jiān)控服務(wù)器通過 Inter/Intra 輪詢網(wǎng)絡(luò)攝像機(jī)獲取視頻。因?yàn)?Windows服 務(wù)程序沒有用戶界面,為了能使一個(gè)Windows服務(wù)程序能夠正常并有效的在系統(tǒng)環(huán)境下工作,程序員必須實(shí)現(xiàn)一系列的方法來完成其服務(wù)功能。對(duì)于自動(dòng)啟動(dòng)的 Windows服務(wù)程序,它們?cè)?Windows啟動(dòng)或是重啟之后用戶登錄之前就開始執(zhí)行了。可擴(kuò)展性好。 本系統(tǒng)采用 DirectShow 網(wǎng) 絡(luò)組播技術(shù)實(shí)現(xiàn)了視頻捕獲、視頻壓縮、網(wǎng)絡(luò)傳輸、視頻解碼和實(shí)時(shí)回放,減小了網(wǎng)絡(luò)帶寬占用,高效的傳輸視頻數(shù)據(jù),獨(dú)立于硬件。這些啟動(dòng)方式包括了自動(dòng)啟動(dòng)和手動(dòng)啟動(dòng)兩種 。因?yàn)?Windows服務(wù)程序一般是沒有用戶界面的,所以你也要通過命令行工具或是下面圖中的工具來停止它,或是在系統(tǒng)關(guān)閉時(shí)使得 Windows服務(wù)程序自動(dòng)停止。對(duì)于網(wǎng)絡(luò)攝像機(jī) 傳輸?shù)囊曨l數(shù)據(jù),需要專門的 Filter 來處理并在DirectShow 的框架下或回放,或保存。 DirectShow 為多媒體流的捕捉和回放以及二次開發(fā)提供了強(qiáng)有力的支持。 TCP/IP 協(xié)議 在 TCP/IP協(xié)議組分兩種協(xié)議:網(wǎng)絡(luò)層的協(xié)議 , 應(yīng)用層的協(xié)議 ? 網(wǎng)絡(luò)層 協(xié)議 網(wǎng)絡(luò)層協(xié)議管理離散的計(jì)算機(jī)間的數(shù)據(jù)傳輸。在機(jī)器 IP 地址和其它信息的基礎(chǔ)上, IP 確保信息包能正確地到達(dá)目的機(jī)器。比如,文件傳輸協(xié)議 (FTP)用戶是看得到的。 IP數(shù)據(jù)包是不可靠的,因?yàn)?IP并沒有做任何事情來確認(rèn)數(shù)據(jù)包是按順序發(fā)送的或者沒有被破壞。 ? TCP 如果 IP數(shù)據(jù)包中有已經(jīng)封好的 TCP數(shù)據(jù)包,那么 IP 將把它們向上傳送到 TCP 層。應(yīng)用程序輪流將信息送回 TCP 層, TCP 層便將它們向下傳送到 IP層,設(shè)備驅(qū)動(dòng)程序和物理介質(zhì),最后到接收方。無連接的服務(wù)進(jìn)程也必須首先啟動(dòng)以指定本地的套接字地址否則客戶進(jìn)程的數(shù)據(jù)服務(wù)請(qǐng)求傳送不到服務(wù)器進(jìn)程。 客戶端連接是指由客戶端的 socket 提出連接請(qǐng)求,要連接的目標(biāo)是服務(wù)器端的 socket。當(dāng)服務(wù)器端 socket 監(jiān)聽到或者說 接收到客戶端 socket 的連接請(qǐng)求,它就響應(yīng)客戶端 socket 的請(qǐng)求建立一個(gè)新的 socket 句柄并與客戶 端連接,而服務(wù)器端 socket 繼續(xù)處于監(jiān)聽狀態(tài),還可以接收其它客戶端 socket 的連接請(qǐng)求。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. 7 const int MAXCONNECTIONS = 3。 private ManualResetEvent ShutDownReady。 if USING_NET11 IPHostEntry ipEntry = ( strHostName )。 } return aryLocalAddr。t close the listener // while there is an outstanding async call active. And you can39。 // Disconnect each client foreach (SockWrapper s in m_aryClients) { try { ()。