VC++实现对远程计算机屏幕的监视
生活随笔
收集整理的這篇文章主要介紹了
VC++实现对远程计算机屏幕的监视
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
摘要:本文介紹了一種通過
套接字網(wǎng)絡(luò)編程和
屏幕捕獲技術(shù)實現(xiàn)的對遠程計算機屏幕進行監(jiān)視的方法。
關(guān)鍵詞:套接字;屏幕 捕捉;遠程監(jiān)視;網(wǎng)絡(luò)
前言
在實際工程中,經(jīng)常有施工現(xiàn)場和控制中心不在一起的情況,在這種情況一般多由工程技術(shù)人員往返穿梭其間來實現(xiàn)對遠程施工現(xiàn)場的情況了解和對控制中心的矯正控制。顯然這種工作方式的效率是很低下的,沒有充分發(fā)揮計算機網(wǎng)絡(luò)的強大優(yōu)勢,其實通過網(wǎng)絡(luò)編程完全可以使技術(shù)人員在控制中心對位于工程現(xiàn)場的遠程計算機實施監(jiān)視和控制。雖然互聯(lián)網(wǎng)上有不少遠程終端控制軟件如"超級 間諜"、"冰河"等,但由于其帶有 黑軟的性質(zhì),不能保證其在編程時沒有留有其他后門,因此從 計算機安全的角度出發(fā)應(yīng)當(dāng)自行開發(fā)此類軟件。為避免本文所述技術(shù)被用于制造黑客類軟件,本文將不準(zhǔn)備對遠程終端的控制部分做進一步的介紹,而將重點放在對遠程計算機屏幕界面的監(jiān)視上。 1 數(shù)據(jù)信息在網(wǎng)絡(luò)上的傳送
由于本地計算機是通過網(wǎng)絡(luò)來對遠程計算機實施監(jiān)控,因此需要對網(wǎng)卡進行編程以實現(xiàn)往來于雙方的數(shù)據(jù)信息在網(wǎng)絡(luò)上的順暢通訊。可供選擇的方案有套接字、郵槽、 命名管道等多種,本文在此選用開發(fā)和應(yīng)用都比較靈活的流式套接字作為網(wǎng)絡(luò)通訊的基礎(chǔ)。考慮到實際情況,遠程被監(jiān)視主機隨時為本地監(jiān)控主機提供屏幕信息的服務(wù),因此整個系統(tǒng)可以劃分為兩大模塊-- 服務(wù)器端和 客戶機端,分別運行于遠程主機和本地監(jiān)控主機,由客戶機向服務(wù)器發(fā)出連接請求,在建立連接后由服務(wù)器定時發(fā)送遠程屏幕信息給客戶機,客戶機接收到服務(wù)器發(fā)來的數(shù)據(jù)后將其顯示在本地主機。
至于用流式套接字對網(wǎng)絡(luò)進行編程的主要過程可用下圖來表示。服務(wù)器方在使用套接字之前,首先必須擁有一個Socket,可用socket()函數(shù) 創(chuàng)建之:
其中AF_INET 和SOCK_STREAM指定了創(chuàng)建的是采用了TCP/IP地址族的流式套接字。該套接字實際上是提供了一個通信端口,通過這個端口可與任何一個具有套接字端口的計算機實施通信。一旦獲取了新的套接字,應(yīng)立即通過bind()將該套接字與本機上的一個端口建立關(guān)聯(lián)。需要預(yù)先對一個指向包含有本機IP地址和端口信息的sockaddr_in結(jié)構(gòu)填充一些必要的信息,如本地端口號和本地主機地址等,并通過bind()將服務(wù)器進程在網(wǎng)絡(luò) 上標(biāo)識出來:
在完成接下來的listen()偵聽后,需要用accept()等待接收客戶端的連接,由于該函數(shù)在沒有客戶端進行申請連接之前會處于阻塞狀態(tài),因此需要為其單獨開辟一個線程,以免影響到程序整體:
在這里通過WSAAsyncSelect()異步選擇函數(shù)來以異步的形式響應(yīng)關(guān)心的網(wǎng)絡(luò)事件FD_CLOSE,并在該事件發(fā)生時發(fā)出自 定義WM_MSG消息,通過響應(yīng)這個消息可以得之當(dāng)前與服務(wù)器聯(lián)系的客戶機程序已關(guān)閉退出,由于服務(wù)器部分是運行于遠程工程現(xiàn)場的,為了使控制中心的監(jiān)控程序(客戶)在下次發(fā)出監(jiān)控請求時能為其提供服務(wù)需要在WM_MSG的消息響應(yīng)函數(shù)里關(guān)閉由accept() 所產(chǎn)生的新的套接字newskt_s,并 重新啟動該線程等待監(jiān)控程序的再次連接。在accept()函數(shù)成功返回后,就可以在 定時器響應(yīng)函數(shù)里用send() 函數(shù)與之建立了連接的監(jiān)控主機定時發(fā)送捕獲的遠程屏幕信息了。
作為客戶的監(jiān)控程序,其實現(xiàn)過程要比服務(wù)器 簡單許多。由于需要接收數(shù)據(jù),因此在異步選擇函數(shù)中需要設(shè)定待監(jiān)測的網(wǎng)絡(luò)事件為FD_CLOSE和FD_READ。在消息響應(yīng)函數(shù)中可以通過對消息 參數(shù)的低位字節(jié)進行判斷而區(qū)分出具體發(fā)生是何種網(wǎng)絡(luò)事件,并對其做出響應(yīng)的反應(yīng)。下面是監(jiān)控端程序網(wǎng)絡(luò)部分的主要代碼:
這時雖以獲取到了屏幕的信息,并將其復(fù)制到內(nèi)存位圖之中,但此時還不能直接將其發(fā)送出去,需要調(diào)用CBitmap 類的成員函數(shù)GetBitmapBits()來將圖像信息從內(nèi)存位圖拷貝到緩存,并通過套接字的send()函數(shù)將緩存中存放的屏幕信息通過網(wǎng)絡(luò)從現(xiàn)場主機發(fā)送到控制中心。
現(xiàn)場主機的屏幕信息在控制中心的再現(xiàn),基本上是屏幕截取的逆過程:先建立一個同客戶區(qū)相關(guān)的設(shè)備環(huán)境并建立一個與之兼容的設(shè)備環(huán)境,然后按位圖格式在內(nèi)存中創(chuàng)建一個與之兼容的內(nèi)存位圖。在從網(wǎng)絡(luò)接收完一屏信息后,通過CBitmap的成員函數(shù)SetBitmapBits()把緩存中的屏幕信息按位圖格式拷貝到內(nèi)存位圖,最后完成對內(nèi)存位圖的顯示。其主要過程如下:
服務(wù)程序的自動加載及擴展
從功能上看,服務(wù)端程序只負(fù)責(zé)為遠程客戶提供服務(wù),在全部運行期間根本不需要人為的外來干預(yù),因此可以隱藏其界面并將其作成后臺服務(wù)程序:
另外,由于現(xiàn)在計算機多具有通過Modem實現(xiàn)遠程喚醒的功能,因此如能使服務(wù)程序具備自啟動功能將實現(xiàn)遠程現(xiàn)場主機的無人值守。自啟動有多種方式:在Autoexec.bat、win.ini等文件中加入啟動命令、在"啟動"菜單里加入指向程序的快捷方式、修改注冊表等。其中由于注冊表通常被人為改動的機會要小的多,因此通過修改注冊表實現(xiàn)自啟動是一種比較安全的方法。本文采取的方法是:先通過API函數(shù)CopyFile()將服務(wù)程序復(fù)制到系統(tǒng)目錄,然后對HKEY_LOCAL_MACHINE 的Software/Microsoft/Windows/CurrentVersion/Run寫入一個字符串鍵值,該鍵值的內(nèi)容是服務(wù)程序在系統(tǒng)目錄下的全路徑:
至于監(jiān)控中心對現(xiàn)場主機的遠程控制,則主要是通過向?qū)Ψ匠绦虬l(fā)送用以標(biāo)識消息的數(shù)據(jù)并在遠程主機接收完畢后用SendMessage()向指定窗口發(fā)送消息來完成的,可用CreateProcess();來啟動現(xiàn)場主機的程序以響應(yīng)消息。由于該部分技術(shù)亦可用來編寫黑客軟件,故本文在此不便作進一步的描述。
小結(jié):
本文主要針對基于流式套接字的低層網(wǎng)絡(luò)通訊模塊和建立在該模塊基礎(chǔ)之上的屏幕截取和復(fù)原技術(shù)的設(shè)計、實現(xiàn)作了較為詳細(xì)的介紹。本文所述監(jiān)控系統(tǒng)在實際應(yīng)用中取得了較好的效果。使工程技術(shù)人員能在控制中心及時了解到位于工程現(xiàn)場的計算機屏幕上的指示圖表的動態(tài)顯示,并根據(jù)監(jiān)視結(jié)果作出及時的決策。本文所述程序在Windows 2000 Professional下,由Microsoft Visual C++編譯通過。
關(guān)鍵詞:套接字;屏幕 捕捉;遠程監(jiān)視;網(wǎng)絡(luò)
前言
在實際工程中,經(jīng)常有施工現(xiàn)場和控制中心不在一起的情況,在這種情況一般多由工程技術(shù)人員往返穿梭其間來實現(xiàn)對遠程施工現(xiàn)場的情況了解和對控制中心的矯正控制。顯然這種工作方式的效率是很低下的,沒有充分發(fā)揮計算機網(wǎng)絡(luò)的強大優(yōu)勢,其實通過網(wǎng)絡(luò)編程完全可以使技術(shù)人員在控制中心對位于工程現(xiàn)場的遠程計算機實施監(jiān)視和控制。雖然互聯(lián)網(wǎng)上有不少遠程終端控制軟件如"超級 間諜"、"冰河"等,但由于其帶有 黑軟的性質(zhì),不能保證其在編程時沒有留有其他后門,因此從 計算機安全的角度出發(fā)應(yīng)當(dāng)自行開發(fā)此類軟件。為避免本文所述技術(shù)被用于制造黑客類軟件,本文將不準(zhǔn)備對遠程終端的控制部分做進一步的介紹,而將重點放在對遠程計算機屏幕界面的監(jiān)視上。 1 數(shù)據(jù)信息在網(wǎng)絡(luò)上的傳送
由于本地計算機是通過網(wǎng)絡(luò)來對遠程計算機實施監(jiān)控,因此需要對網(wǎng)卡進行編程以實現(xiàn)往來于雙方的數(shù)據(jù)信息在網(wǎng)絡(luò)上的順暢通訊。可供選擇的方案有套接字、郵槽、 命名管道等多種,本文在此選用開發(fā)和應(yīng)用都比較靈活的流式套接字作為網(wǎng)絡(luò)通訊的基礎(chǔ)。考慮到實際情況,遠程被監(jiān)視主機隨時為本地監(jiān)控主機提供屏幕信息的服務(wù),因此整個系統(tǒng)可以劃分為兩大模塊-- 服務(wù)器端和 客戶機端,分別運行于遠程主機和本地監(jiān)控主機,由客戶機向服務(wù)器發(fā)出連接請求,在建立連接后由服務(wù)器定時發(fā)送遠程屏幕信息給客戶機,客戶機接收到服務(wù)器發(fā)來的數(shù)據(jù)后將其顯示在本地主機。
至于用流式套接字對網(wǎng)絡(luò)進行編程的主要過程可用下圖來表示。服務(wù)器方在使用套接字之前,首先必須擁有一個Socket,可用socket()函數(shù) 創(chuàng)建之:
| sock=socket(AF_INET,SOCK_STREAM,0); |
其中AF_INET 和SOCK_STREAM指定了創(chuàng)建的是采用了TCP/IP地址族的流式套接字。該套接字實際上是提供了一個通信端口,通過這個端口可與任何一個具有套接字端口的計算機實施通信。一旦獲取了新的套接字,應(yīng)立即通過bind()將該套接字與本機上的一個端口建立關(guān)聯(lián)。需要預(yù)先對一個指向包含有本機IP地址和端口信息的sockaddr_in結(jié)構(gòu)填充一些必要的信息,如本地端口號和本地主機地址等,并通過bind()將服務(wù)器進程在網(wǎng)絡(luò) 上標(biāo)識出來:
| sockin_s.sin_family=AF_INET; sockin_s.sin_addr.s_addr=0; sockin_s.sin_port=htons(PORT); bind(sock,(LPSOCKADDR)&sockin_s,sizeof(sockin_s)); |
在完成接下來的listen()偵聽后,需要用accept()等待接收客戶端的連接,由于該函數(shù)在沒有客戶端進行申請連接之前會處于阻塞狀態(tài),因此需要為其單獨開辟一個線程,以免影響到程序整體:
| AfxBeginThread(Server,NULL);//創(chuàng)建一個新的線程 …… UINT Server(LPVOID lpVoid) { CSurveillant_ServerView* pView=((CSurveillant_ServerView*)((CFrameWnd*) AfxGetApp()->m_pMainWnd)->GetActiveView()); int nLen=sizeof(SOCKADDR); pView->newskt_s= accept(pView->sock,(LPSOCKADDR)& pView->sockin_s,(LPINT)& nLen); WSAAsyncSelect(pView->newskt_s,pView->m_hWnd,WM_MSG,FD_CLOSE); pView->SetTimer(0,2500,NULL); return 1; } |
在這里通過WSAAsyncSelect()異步選擇函數(shù)來以異步的形式響應(yīng)關(guān)心的網(wǎng)絡(luò)事件FD_CLOSE,并在該事件發(fā)生時發(fā)出自 定義WM_MSG消息,通過響應(yīng)這個消息可以得之當(dāng)前與服務(wù)器聯(lián)系的客戶機程序已關(guān)閉退出,由于服務(wù)器部分是運行于遠程工程現(xiàn)場的,為了使控制中心的監(jiān)控程序(客戶)在下次發(fā)出監(jiān)控請求時能為其提供服務(wù)需要在WM_MSG的消息響應(yīng)函數(shù)里關(guān)閉由accept() 所產(chǎn)生的新的套接字newskt_s,并 重新啟動該線程等待監(jiān)控程序的再次連接。在accept()函數(shù)成功返回后,就可以在 定時器響應(yīng)函數(shù)里用send() 函數(shù)與之建立了連接的監(jiān)控主機定時發(fā)送捕獲的遠程屏幕信息了。
作為客戶的監(jiān)控程序,其實現(xiàn)過程要比服務(wù)器 簡單許多。由于需要接收數(shù)據(jù),因此在異步選擇函數(shù)中需要設(shè)定待監(jiān)測的網(wǎng)絡(luò)事件為FD_CLOSE和FD_READ。在消息響應(yīng)函數(shù)中可以通過對消息 參數(shù)的低位字節(jié)進行判斷而區(qū)分出具體發(fā)生是何種網(wǎng)絡(luò)事件,并對其做出響應(yīng)的反應(yīng)。下面是監(jiān)控端程序網(wǎng)絡(luò)部分的主要代碼:
| …… IPaddr=inet_addr(strIP); sock=socket(AF_INET,SOCK_STREAM,0); //創(chuàng)建套接字 sockin_c.sin_family=AF_INET; sockin_c.sin_addr.S_un.S_addr=IPaddr; sockin_c.sin_port=m_Port; connect(sock,(LPSOCKADDR)&sockin_c,sizeof(sockin_c));//連接服務(wù)器 …… WSAAsyncSelect(sock,m_hWnd,WM_MSG,FD_READ|FD_CLOSE); …… |
通過異步選擇函數(shù)的設(shè)定,在有數(shù)據(jù)到達時會由FD_READ觸發(fā)WM_MSG消息,并在處理函數(shù)中通過調(diào)用recv ()將遠程主機的屏幕信息從網(wǎng)絡(luò)接收到緩存,并完成在本地機的重顯。通過以上幾步,已經(jīng)初步具備了在遠程服務(wù)器和本地客戶機之間的網(wǎng)絡(luò)通訊能力,可以完成屏幕信息的網(wǎng)絡(luò)傳送任務(wù)。
對遠程計算機屏幕的捕捉和顯示
前面部分的工作只是為整個監(jiān)控系統(tǒng)提供一個低層的網(wǎng)絡(luò)數(shù)據(jù)通訊的能力,也可以說是為現(xiàn)場主機和監(jiān)控中心提供一個通信用信道。至于本文的中心議題--遠程監(jiān)視工作則需要分別在現(xiàn)場主機和監(jiān)控中心中完成對屏幕的捕捉和信息的再現(xiàn)。屏幕的捕捉可以采取先獲取桌面窗口指針并建立一個與之兼容的設(shè)備環(huán)境,然后創(chuàng)建一個與桌面窗口指針相兼容的內(nèi)存位圖并以位圖的形式將屏幕圖像拷貝到新創(chuàng)建的位圖之中:
| char dot[1572864]; //1024*768*2 CBitmap bmp; //內(nèi)存位圖 CDC wdc; //設(shè)備環(huán)境 CDC* pDC; //指向桌面窗口的設(shè)備環(huán)境指針 …… static CWindowDC ddc(GetDesktopWindow()); //引用桌面窗口指針定義對象ddc pDC=&ddc; //將指針pdc指向ddc wdc.CreateCompatibleDC(pDC); //建立與ddc兼容的設(shè)備環(huán)境 bmp.CreateCompatibleBitmap(pDC,1024,768); //建立與ddc兼容的位圖 wdc.SelectObject(&bmp); //選擇bmp …… wdc.BitBlt(0,0,1024,768,pDC,0,0,SRCCOPY); //把桌面圖像復(fù)制到wdc的bmp中 |
這時雖以獲取到了屏幕的信息,并將其復(fù)制到內(nèi)存位圖之中,但此時還不能直接將其發(fā)送出去,需要調(diào)用CBitmap 類的成員函數(shù)GetBitmapBits()來將圖像信息從內(nèi)存位圖拷貝到緩存,并通過套接字的send()函數(shù)將緩存中存放的屏幕信息通過網(wǎng)絡(luò)從現(xiàn)場主機發(fā)送到控制中心。
現(xiàn)場主機的屏幕信息在控制中心的再現(xiàn),基本上是屏幕截取的逆過程:先建立一個同客戶區(qū)相關(guān)的設(shè)備環(huán)境并建立一個與之兼容的設(shè)備環(huán)境,然后按位圖格式在內(nèi)存中創(chuàng)建一個與之兼容的內(nèi)存位圖。在從網(wǎng)絡(luò)接收完一屏信息后,通過CBitmap的成員函數(shù)SetBitmapBits()把緩存中的屏幕信息按位圖格式拷貝到內(nèi)存位圖,最后完成對內(nèi)存位圖的顯示。其主要過程如下:
| CDC* pDC=GetDC(); //引用用戶窗口指針定義對象pDC wdc.CreateCompatibleDC(pDC); //建立與pDC兼容的device context bmp.CreateCompatibleBitmap(pDC,1024,768); //建立與pDC兼容的位圖 wdc.SelectObject(&bmp); …… iReadLen = recv(sock,buffer,60000,0); //從網(wǎng)絡(luò)接收數(shù)據(jù) for(i=0;i<iReadLen;i++) { dot[pointer]=buffer[i]; pointer++; if(pointer==1572864) //判斷接收到的信息是否已滿一屏 { GetClientRect(&rect); bmp.SetBitmapBits(1572864,(LPVOID)dot); //把內(nèi)存數(shù)據(jù)復(fù)制到bmp中 //把bmp中圖像復(fù)制到用戶窗口中 pDC->StretchBlt(0,0,rect.Width(),rect.Height(),&wdc,0,0,1024,768,SRCCOPY); pointer=0; //接收完一屏后指針復(fù)位,準(zhǔn)備接收下一屏 } } |
服務(wù)程序的自動加載及擴展
從功能上看,服務(wù)端程序只負(fù)責(zé)為遠程客戶提供服務(wù),在全部運行期間根本不需要人為的外來干預(yù),因此可以隱藏其界面并將其作成后臺服務(wù)程序:
| BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) { …… cs.cx=200; cs.cy=10; cs.style=WS_POPUP; cs.dwExStyle|=WS_EX_TOOLWINDOW; return TRUE; } |
另外,由于現(xiàn)在計算機多具有通過Modem實現(xiàn)遠程喚醒的功能,因此如能使服務(wù)程序具備自啟動功能將實現(xiàn)遠程現(xiàn)場主機的無人值守。自啟動有多種方式:在Autoexec.bat、win.ini等文件中加入啟動命令、在"啟動"菜單里加入指向程序的快捷方式、修改注冊表等。其中由于注冊表通常被人為改動的機會要小的多,因此通過修改注冊表實現(xiàn)自啟動是一種比較安全的方法。本文采取的方法是:先通過API函數(shù)CopyFile()將服務(wù)程序復(fù)制到系統(tǒng)目錄,然后對HKEY_LOCAL_MACHINE 的Software/Microsoft/Windows/CurrentVersion/Run寫入一個字符串鍵值,該鍵值的內(nèi)容是服務(wù)程序在系統(tǒng)目錄下的全路徑:
| DWORD type=REG_SZ; DWORD size=MAX_PATH; LPCTSTR Rgspath="Software//Microsoft//Windows//CurrentVersion//Run" ; …… GetSystemDirectory(SysPath,size); //獲取系統(tǒng)目錄 GetModuleFileName(NULL,CurrentPath,size); //獲取程序路徑 FileCurrentName = CurrentPath; FileNewName = lstrcat(SysPath,"//Surveillant.exe"); ret = CopyFile(FileCurrentName,FileNewName,TRUE); //拷貝程序到系統(tǒng)目錄 …… //打開注冊表 ret=RegOpenKeyEx(HKEY_LOCAL_MACHINE,Rgspath,0,KEY_WRITE, &hKEY); …… //寫入注冊表 ret=RegSetValueEx(hKEY,"Surveillant",NULL,type, FileNewName,size); …… //關(guān)閉注冊表 RegCloseKey(hKEY); |
至于監(jiān)控中心對現(xiàn)場主機的遠程控制,則主要是通過向?qū)Ψ匠绦虬l(fā)送用以標(biāo)識消息的數(shù)據(jù)并在遠程主機接收完畢后用SendMessage()向指定窗口發(fā)送消息來完成的,可用CreateProcess();來啟動現(xiàn)場主機的程序以響應(yīng)消息。由于該部分技術(shù)亦可用來編寫黑客軟件,故本文在此不便作進一步的描述。
小結(jié):
本文主要針對基于流式套接字的低層網(wǎng)絡(luò)通訊模塊和建立在該模塊基礎(chǔ)之上的屏幕截取和復(fù)原技術(shù)的設(shè)計、實現(xiàn)作了較為詳細(xì)的介紹。本文所述監(jiān)控系統(tǒng)在實際應(yīng)用中取得了較好的效果。使工程技術(shù)人員能在控制中心及時了解到位于工程現(xiàn)場的計算機屏幕上的指示圖表的動態(tài)顯示,并根據(jù)監(jiān)視結(jié)果作出及時的決策。本文所述程序在Windows 2000 Professional下,由Microsoft Visual C++編譯通過。
總結(jié)
以上是生活随笔為你收集整理的VC++实现对远程计算机屏幕的监视的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python展示_python展示ppt
- 下一篇: ege函数库_基于c++ ege图形库实