日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

VC++实现对远程计算机屏幕的监视

發(fā)布時間:2025/3/15 c/c++ 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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)建之:

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)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。