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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

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

發布時間:2025/3/15 c/c++ 16 豆豆
生活随笔 收集整理的這篇文章主要介紹了 VC++实现对远程计算机屏幕的监视 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
摘要:本文介紹了一種通過 套接字網絡編程和 屏幕捕獲技術實現的對遠程計算機屏幕進行監視的方法。

   關鍵詞:套接字;屏幕 捕捉;遠程監視;網絡

   前言

  在實際工程中,經常有施工現場和控制中心不在一起的情況,在這種情況一般多由工程技術人員往返穿梭其間來實現對遠程施工現場的情況了解和對控制中心的矯正控制。顯然這種工作方式的效率是很低下的,沒有充分發揮計算機網絡的強大優勢,其實通過網絡編程完全可以使技術人員在控制中心對位于工程現場的遠程計算機實施監視和控制。雖然互聯網上有不少遠程終端控制軟件如"超級 間諜"、"冰河"等,但由于其帶有 黑軟的性質,不能保證其在編程時沒有留有其他后門,因此從 計算機安全的角度出發應當自行開發此類軟件。為避免本文所述技術被用于制造黑客類軟件,本文將不準備對遠程終端的控制部分做進一步的介紹,而將重點放在對遠程計算機屏幕界面的監視上。 1 數據信息在網絡上的傳送

  由于本地計算機是通過網絡來對遠程計算機實施監控,因此需要對網卡進行編程以實現往來于雙方的數據信息在網絡上的順暢通訊。可供選擇的方案有套接字、郵槽、 命名管道等多種,本文在此選用開發和應用都比較靈活的流式套接字作為網絡通訊的基礎。考慮到實際情況,遠程被監視主機隨時為本地監控主機提供屏幕信息的服務,因此整個系統可以劃分為兩大模塊-- 服務器端客戶機端,分別運行于遠程主機和本地監控主機,由客戶機向服務器發出連接請求,在建立連接后由服務器定時發送遠程屏幕信息給客戶機,客戶機接收到服務器發來的數據后將其顯示在本地主機。

  至于用流式套接字對網絡進行編程的主要過程可用下圖來表示。服務器方在使用套接字之前,首先必須擁有一個Socket,可用socket()函數 創建之:

sock=socket(AF_INET,SOCK_STREAM,0);


  其中AF_INET 和SOCK_STREAM指定了創建的是采用了TCP/IP地址族的流式套接字。該套接字實際上是提供了一個通信端口,通過這個端口可與任何一個具有套接字端口的計算機實施通信。一旦獲取了新的套接字,應立即通過bind()將該套接字與本機上的一個端口建立關聯。需要預先對一個指向包含有本機IP地址和端口信息的sockaddr_in結構填充一些必要的信息,如本地端口號和本地主機地址等,并通過bind()將服務器進程在網絡 上標識出來:

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()等待接收客戶端的連接,由于該函數在沒有客戶端進行申請連接之前會處于阻塞狀態,因此需要為其單獨開辟一個線程,以免影響到程序整體:

AfxBeginThread(Server,NULL);//創建一個新的線程
……
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()異步選擇函數來以異步的形式響應關心的網絡事件FD_CLOSE,并在該事件發生時發出自 定義WM_MSG消息,通過響應這個消息可以得之當前與服務器聯系的客戶機程序已關閉退出,由于服務器部分是運行于遠程工程現場的,為了使控制中心的監控程序(客戶)在下次發出監控請求時能為其提供服務需要在WM_MSG的消息響應函數里關閉由accept() 所產生的新的套接字newskt_s,并 重新啟動該線程等待監控程序的再次連接。在accept()函數成功返回后,就可以在 定時器響應函數里用send() 函數與之建立了連接的監控主機定時發送捕獲的遠程屏幕信息了。

  作為客戶的監控程序,其實現過程要比服務器 簡單許多。由于需要接收數據,因此在異步選擇函數中需要設定待監測的網絡事件為FD_CLOSE和FD_READ。在消息響應函數中可以通過對消息 參數的低位字節進行判斷而區分出具體發生是何種網絡事件,并對其做出響應的反應。下面是監控端程序網絡部分的主要代碼:

……
IPaddr=inet_addr(strIP);
sock=socket(AF_INET,SOCK_STREAM,0); //創建套接字
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));//連接服務器
……
WSAAsyncSelect(sock,m_hWnd,WM_MSG,FD_READ|FD_CLOSE);
……


  通過異步選擇函數的設定,在有數據到達時會由FD_READ觸發WM_MSG消息,并在處理函數中通過調用recv ()將遠程主機的屏幕信息從網絡接收到緩存,并完成在本地機的重顯。通過以上幾步,已經初步具備了在遠程服務器和本地客戶機之間的網絡通訊能力,可以完成屏幕信息的網絡傳送任務。


  對遠程計算機屏幕的捕捉和顯示

  前面部分的工作只是為整個監控系統提供一個低層的網絡數據通訊的能力,也可以說是為現場主機和監控中心提供一個通信用信道。至于本文的中心議題--遠程監視工作則需要分別在現場主機和監控中心中完成對屏幕的捕捉和信息的再現。屏幕的捕捉可以采取先獲取桌面窗口指針并建立一個與之兼容的設備環境,然后創建一個與桌面窗口指針相兼容的內存位圖并以位圖的形式將屏幕圖像拷貝到新創建的位圖之中:

char dot[1572864]; //1024*768*2
CBitmap bmp; //內存位圖
CDC wdc; //設備環境
CDC* pDC; //指向桌面窗口的設備環境指針
……
static CWindowDC ddc(GetDesktopWindow()); //引用桌面窗口指針定義對象ddc
pDC=&ddc; //將指針pdc指向ddc
wdc.CreateCompatibleDC(pDC); //建立與ddc兼容的設備環境
bmp.CreateCompatibleBitmap(pDC,1024,768); //建立與ddc兼容的位圖
wdc.SelectObject(&bmp); //選擇bmp
……
wdc.BitBlt(0,0,1024,768,pDC,0,0,SRCCOPY); //把桌面圖像復制到wdc的bmp中

  這時雖以獲取到了屏幕的信息,并將其復制到內存位圖之中,但此時還不能直接將其發送出去,需要調用CBitmap 類的成員函數GetBitmapBits()來將圖像信息從內存位圖拷貝到緩存,并通過套接字的send()函數將緩存中存放的屏幕信息通過網絡從現場主機發送到控制中心。

  現場主機的屏幕信息在控制中心的再現,基本上是屏幕截取的逆過程:先建立一個同客戶區相關的設備環境并建立一個與之兼容的設備環境,然后按位圖格式在內存中創建一個與之兼容的內存位圖。在從網絡接收完一屏信息后,通過CBitmap的成員函數SetBitmapBits()把緩存中的屏幕信息按位圖格式拷貝到內存位圖,最后完成對內存位圖的顯示。其主要過程如下:

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); //從網絡接收數據
for(i=0;i<iReadLen;i++)
{
 dot[pointer]=buffer[i];
 pointer++;
 if(pointer==1572864) //判斷接收到的信息是否已滿一屏
 {
  GetClientRect(&rect);
  bmp.SetBitmapBits(1572864,(LPVOID)dot); //把內存數據復制到bmp中
  //把bmp中圖像復制到用戶窗口中
  pDC->StretchBlt(0,0,rect.Width(),rect.Height(),&wdc,0,0,1024,768,SRCCOPY);
  pointer=0; //接收完一屏后指針復位,準備接收下一屏
 }
}

   服務程序的自動加載及擴展

  從功能上看,服務端程序只負責為遠程客戶提供服務,在全部運行期間根本不需要人為的外來干預,因此可以隱藏其界面并將其作成后臺服務程序:

BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
 ……
 cs.cx=200;
 cs.cy=10;
 cs.style=WS_POPUP;
 cs.dwExStyle|=WS_EX_TOOLWINDOW;
 return TRUE;
}

  另外,由于現在計算機多具有通過Modem實現遠程喚醒的功能,因此如能使服務程序具備自啟動功能將實現遠程現場主機的無人值守。自啟動有多種方式:在Autoexec.bat、win.ini等文件中加入啟動命令、在"啟動"菜單里加入指向程序的快捷方式、修改注冊表等。其中由于注冊表通常被人為改動的機會要小的多,因此通過修改注冊表實現自啟動是一種比較安全的方法。本文采取的方法是:先通過API函數CopyFile()將服務程序復制到系統目錄,然后對HKEY_LOCAL_MACHINE 的Software/Microsoft/Windows/CurrentVersion/Run寫入一個字符串鍵值,該鍵值的內容是服務程序在系統目錄下的全路徑:

DWORD type=REG_SZ;
DWORD size=MAX_PATH;
LPCTSTR Rgspath="Software//Microsoft//Windows//CurrentVersion//Run" ;
……
GetSystemDirectory(SysPath,size); //獲取系統目錄
GetModuleFileName(NULL,CurrentPath,size); //獲取程序路徑
FileCurrentName = CurrentPath;
FileNewName = lstrcat(SysPath,"//Surveillant.exe");
ret = CopyFile(FileCurrentName,FileNewName,TRUE); //拷貝程序到系統目錄
……
//打開注冊表
ret=RegOpenKeyEx(HKEY_LOCAL_MACHINE,Rgspath,0,KEY_WRITE, &hKEY);
……
//寫入注冊表
ret=RegSetValueEx(hKEY,"Surveillant",NULL,type, FileNewName,size);
……
//關閉注冊表
RegCloseKey(hKEY);

  至于監控中心對現場主機的遠程控制,則主要是通過向對方程序發送用以標識消息的數據并在遠程主機接收完畢后用SendMessage()向指定窗口發送消息來完成的,可用CreateProcess();來啟動現場主機的程序以響應消息。由于該部分技術亦可用來編寫黑客軟件,故本文在此不便作進一步的描述。

   小結:

  本文主要針對基于流式套接字的低層網絡通訊模塊和建立在該模塊基礎之上的屏幕截取和復原技術的設計、實現作了較為詳細的介紹。本文所述監控系統在實際應用中取得了較好的效果。使工程技術人員能在控制中心及時了解到位于工程現場的計算機屏幕上的指示圖表的動態顯示,并根據監視結果作出及時的決策。本文所述程序在Windows 2000 Professional下,由Microsoft Visual C++編譯通過。

總結

以上是生活随笔為你收集整理的VC++实现对远程计算机屏幕的监视的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。