【正文】
tialization succeeded. Now, start serving up frames //初始化成功,現(xiàn)在,啟動(dòng)服務(wù)器發(fā)送幀 DoIt(cam, serv, sw, myImageCodecInfo, myEncoderParameters)。 myEncoderParameter = new EncoderParameter(, JPEGQUALITY)。 += new TcpSend(Send)。 serv = new TcpServer(TCPLISTENPORT, ()[3])。 // Set up logging //建立日志記錄 StreamWriter sw = (d:\)。 Capture cam = null。 // Depends on video device caps. Generally 430. const int VIDEOWIDTH = 640。 } /// summary /// Stop this service. /// 停止服務(wù) /// The Run() Method tests for this thread state each second /// 每秒都為這個(gè)進(jìn)程啟動(dòng)方法測(cè)試 /// /summary protected override void OnStop() { // Set exit condition //設(shè)置退出狀態(tài) bShutDown = true。 private volatile int iConnectionCount。 } } region Member Variables private const int MAXOUTSTANDINGPACKETS = 3。 WebCamService ServiceToRun = new WebCamService() 。 = WebCamService。 public delegate void TcpReceive(Object sender, ref object o, ref byte [] b, int ByteCount)。 byBuff = new byte[256]。 } // Wrapper for each client (stored in m_aryClients) internal class SockWrapper { // The buffer is used by receive public Socket Client。 } } } } // Remove a connection from the list of active connections private void RemoveConnection(SockWrapper s) { try { ( )。 // Restablish the callback AsyncCallback receiveData = new AsyncCallback( OnReceivedData )。T setup // the async listen, and DO set the event // to say we are done. ()。 ( , 0, , , receiveData, s )。 lock (this) { if (!m_bShuttingDown) { // Wrap the client and add it to the array SockWrapper s = new SockWrapper(client)。 if (Send != null) Send(this, ref , ref bSend)。 } catch { m_bShuttingDown = true。s IP address m_sockListener = new Socket( , , )。 private void _TcpServer(int nPortListen, IPAddress ip) { try { // Initialize member vars m_aryClients = new ArrayList(5)。 } } public event TcpConnected Connected。s no way to clean up // nicely. Moral: Always call Dispose. //Dispose()。 ()。 t = new TcpClient((), )。 // Disconnect each client foreach (SockWrapper s in m_aryClients) { try { ()。t close the listener // while there is an outstanding async call active. And you can39。 } return aryLocalAddr。if USING_NET11 IPHostEntry ipEntry = ( strHostName )。 private ManualResetEvent ShutDownReady。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。當(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)求。 客戶(hù)端連接是指由客戶(hù)端的socket提出連接請(qǐng)求,要連接的目標(biāo)是服務(wù)器端的socket。無(wú)連接的服務(wù)進(jìn)程也必須首先啟動(dòng)以指定本地的套接字地址否則客戶(hù)進(jìn)程的數(shù)據(jù)服務(wù)請(qǐng)求傳送不到服務(wù)器進(jìn)程。應(yīng)用程序輪流將信息送回TCP層,TCP層便將它們向下傳送到IP層,設(shè)備驅(qū)動(dòng)程序和物理介質(zhì),最后到接收方。 TCP如果IP數(shù)據(jù)包中有已經(jīng)封好的TCP數(shù)據(jù)包,那么IP將把它們向上傳送到TCP層。IP數(shù)據(jù)包中含有發(fā)送它的主機(jī)的地址(源地址)和接收它的主機(jī)的地址(目的地址)。在傳輸時(shí),用戶(hù)和遠(yuǎn)程計(jì)算機(jī)的交換的一部分是能看到的。216。它是在許多信息的基礎(chǔ)上工作的,好比說(shuō)是機(jī)器的IP地址。 TCP/IP協(xié)議在TCP/IP協(xié)議組分兩種協(xié)議:網(wǎng)絡(luò)層的協(xié)議,應(yīng)用層的協(xié)議216。DirectShow 為多媒體流的捕捉和回放以及二次開(kāi)發(fā)提供了強(qiáng)有力的支持。對(duì)于網(wǎng)絡(luò)攝像機(jī)傳輸?shù)囊曨l數(shù)據(jù),需要專(zhuān)門(mén)的Filter 來(lái)處理并在DirectShow 的框架下或回放,或保存。 將程序生成的debug中的文件復(fù)制到w文件夾216。因?yàn)閃indows服務(wù)程序沒(méi)有用戶(hù)界面,為了能使一個(gè)Windows服務(wù)程序能夠正常并有效的在系統(tǒng)環(huán)境下工作,程序員必須實(shí)現(xiàn)一系列的方法來(lái)完成其服務(wù)功能。對(duì)于自動(dòng)啟動(dòng)的Windows服務(wù)程序,它們?cè)赪indows啟動(dòng)或是重啟之后用戶(hù)登錄之前就開(kāi)始執(zhí)行了??蓴U(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)閃indows服務(wù)程序一般是沒(méi)有用戶(hù)界面的,所以你也要通過(guò)命令行工具或是下面圖中的工具來(lái)停止它,或是在系統(tǒng)關(guān)閉時(shí)使得Windows服務(wù)程序自動(dòng)停止。 首先,在C盤(pán)創(chuàng)建文件夾w216。 用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)用非常廣泛。DirectShow[1]是微軟公司在ActiveMovie 和Video for Windows 的基礎(chǔ)上推出的基于COM 的流媒體處理的開(kāi)發(fā)包,與DirectX 開(kāi)發(fā)包一起發(fā)布。DirectShow 是一個(gè)開(kāi)放的框架,因此只要有合適的Filter 來(lái)分析和解碼,可以支持任何格式。比如,IP協(xié)議為用戶(hù)和遠(yuǎn)程計(jì)算機(jī)提供了信息包的傳輸方法。如果沒(méi)有網(wǎng)絡(luò)工具,用戶(hù)就看不到在系統(tǒng)里工作的IP。用戶(hù)為了傳輸一個(gè)文件請(qǐng)求一個(gè)和其它計(jì)算機(jī)的連接,連接建立后,就開(kāi)始傳輸文件。IP數(shù)據(jù)包是不可靠的,因?yàn)镮P并沒(méi)有做任何事情來(lái)確認(rèn)數(shù)據(jù)包是按順序發(fā)送的或者沒(méi)有被破壞。216。TCP將它的信息送到更高層的應(yīng)用程序,例如Telnet的服務(wù)程序和客戶(hù)程序。 圖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ò)誤代碼表示連接失敗。Socket類(lèi):socket之間的連接可以分為三種類(lèi)型:客戶(hù)端連接,監(jiān)聽(tīng)連接以及服務(wù)器端連接。監(jiān)聽(tīng)連接,服務(wù)器端 socket并不定位具體的客戶(hù)端socket,而是處于等待連接的狀態(tài)。TcpService類(lèi)namespace TCP{ internal class TcpServer : IDisposable { // This is not the max number of connections you can have, it39。 private volatile bool m_bShuttingDown。 // NOTE: DNS lookups are nice and all but quite time consuming. strHostName = ()。 // Verify we got an IP address. if( aryLocalAddr == null || 1 ) { throw new Exception( Unable to get local address )。 } // Shut down the listener public void Dispose()