《遠端控制》-服務端實現(一)
設計總覽
目錄
編譯環境
- 編譯工具:vs2019
- 編譯語言:C/C++
- 作業系統:Windows10
- 輔助工具:git,StarUML
- 網路協議:TCP/IP
- 初步設計模式:客戶端-服務端(C/S)模式
- 後期設計模式:一對多模式、客戶端mvc架構
服務端
- 初始化網路環境 WSAStartup()
- 建立服務端套接字 socket()
- 初始化服務端資訊 sockaddr_in 結構體
- 繫結套接字 bind()
- 監聽listen()
- 連線accept()
- 收發資料 recv send()
- 資料處理
客戶端
- 初始化網路環境
- 建立客戶端套接字socket()
- 初始化客戶端網路資訊 sockaddr_in結構體
- 連線服務端 connect()
- 接收發資料 recv() send()
- 資料處理
資料包設計
- 包頭
- 命令
- 資料長度
- 資料
- 和校驗
功能設計
- 驅動碟符遍歷
- 檔案遍歷
- 檔案刪除
- 檔案下載
- 圖傳操作
- 滑鼠操作
- 鎖屏
- 解鎖屏
IOPC
完成埠CreateIoCompletionPort
重疊結構OVERLAPPED
非同步連線AccepEx
非同步接收WSARecv
非同步傳送WSASend
設計流程
服務端實現(一)
建立服務端專案-Windows桌面嚮導
說明:服務端初步設計,使用Windows桌面嚮導應用應用程式,在設定屬性框裡調成視窗隱藏模式
初步設計完成了網路模組初始化、連線客戶端、接收發資料功能
步驟:
- 服務端專案建立
- 屬性配置,並且忽略4996錯誤
說明:該類主要用於網路層通訊,連線客戶端、接收發資料
CServerSocket()
函式原型:CServerSocket();
函式說明:建構函式 用於初始化網路環境,並建立伺服器socket
InitSockEnv()
函式原型:BOOL InitSockEnv();
函式說明:初始化網路環境,採用1.1版本網路庫
返回值:初始化成功返回TRUE,失敗返回FALSE
主要使用的系統函式:WSAStartup()
~CServerSocket()
函式原型:~CServerSocket();
函式說明:解構函式 用於清除網路環境
主要使用的系統函式:WSACleanup()
operator =
函式原型:CClientSocket& operator =(const CClientSocket&);
函式說明:過載複製建構函式,過載操作符號=,用於安全操作,防止錯誤使用“=”號造成嚴重後果。
InitSocket()
函式原型:bool initSocket();
函式說明:初始化服務端資訊,使用TCP/IP協議族,開啟廣播域模式(0.0.0.0),監聽埠為9527,並繫結到服務端socket,開啟監聽。
返回值:布林,成功返回true,失敗返回fasle
主要使用的系統函式:
-
- bind()
- listen()
AcceptClient()
函式原型:bool AcceptClient();
函式說明:連線客戶端,連線客戶端後得到該客戶端socket。
返回值:布林,成功返回true,失敗返回fasle。
主要使用的系統函式:
-
- accept()
函式原型:SOCKET accept(int sockfd, struct sockaddr* addr, socklen_t* addrlen);
函式說明:
//引數1:套接字描述符,該套介面在listen()後監聽連線
//引數2:由套介面建立時所產生的地址族確定。
//引數3:指向存有addr地址長度的整型數
DealCommand();
函式原型:int DealCommand();
函式說明:接受發資料,解包,取得包裡的命令並返回。
返回值: 成功得到命令 , 失敗得到 -1。
主要使用的系統函式:
-
- recv()
函式原型:int recv( _In_ SOCKET s, _Out_ char *buf, _In_ int len, _In_ int flags);
函式說明:接收資料
- recv()
//引數1:使用接收端的套接字
//引數2:緩衝區,用於接收資料
//引數3:指明緩衝區的長度
//引數4:標誌功能,一般為0
//返回值:若無錯誤發生,recv()返回讀入的位元組數。如果連線已中止,返回0。否則的話,返回SOCKET_ERROR錯誤,使用WSAGetLastError()得到錯誤詳細資訊。
Send()
函式原型:bool Send(const char* pData, int nSize);
函式說明:傳送資料
//引數1:需要傳送的資料
//引數2:資料大小
//返回值:成功傳送返回true,傳送失敗返回fasle
使用的系統函式:
- send()
函式原型:int send(SOCKET s, const char FAR* buf, int len, int flags);
函式說明:傳送資料
//引數1:指定傳送端套接字描述符
//引數2:指明需要傳送的資料緩衝區
//引數3:該緩衝區的大小
//引數4:標誌,一般填0
//返回值:若無錯誤發生,send()返回所傳送資料的總數,否則,返回SOCKET_ERROR錯誤,使用WSAGetLastError()得到錯誤詳細資訊。
getInStance()特例設計
為了防止多次外部多次建立伺服器CServerSocket物件從而初始化多次網路環境造成不可預計的後果,採用安全的程式設計方法
- 將CServerSocket() 建構函式設定為私有成員函式,此時外部無法構造改類
- 在類的私有內建立一個CHelper類用於初始化唯一的CServerSocket物件,而外部無法訪問CHelper類
- 宣告一個CHelper類物件為靜態私有成員,並且在cpp中例項化,從而當程式載入初始化時,首先初始化CHelper類,此時呼叫getInstance()即可初始化CServerSocket物件
- 對外只放出一個靜態函式介面 getInstance(),無法重複建立CServerSocket物件
- 外部只能通過getInstance()得到唯一一個服務端socket。
- 資料包設計
- 建構函式,初始化
- 函式原型:CPacket(WORD nCmd, const BYTE* pData, size_t nSize);
函式說明:資料包封包建構函式,用於把資料封裝成資料包
//引數1:命令
//引數2:資料指標
//引數3:資料大小
- 函式原型:CPacket(const BYTE* pData, size_t& nSize);
函式說明:資料包解包,將包中的資料分配到成員變數中
//引數1:資料指標
//引數2:資料大小 - 資料包類總覽
MakeDriverInfo()
函式原型:int MakeDriverInfo();
函式說明:檢視本地磁碟分割槽,並把資訊打包成資料包
//返回值 int 成功返回0,失敗返回 -1
使用主要系統函式:int __cdecl _chdrive(int _Drive) //通過切換26個字母碟符是否能切換成功來判斷碟符存在
MakeDirectoryInof()
函式原型:int MakeDriverInfo();
函式說明:遍歷磁碟檔案,並將得到的資訊打包成資料包。
//返回值:成功返回0,路徑錯誤返回-1,沒有許可權返回-2,空檔案返回-3。
內部使用主要函式
- int __cdecl _chdir(const char* _Path)
//函式說明:通過切換到輸入的路徑來判斷是否存在該路徑
//引數1:路徑 - int __cdecl _findfirst(const char* _FileName, struct _finddata_t* _FindData)
//函式說明:獲得當前檔案節點
//引數1:檔案路徑 填 “*” 表示匹配所有檔案, “D:\\*.txt” 表示D盤下所有.txt檔案
//引數2:檔案資訊的結構體 out型
//返回值:檔案節點 - int __cdecl _findnext(int _FindHandle, struct _finddata_t* _FindData)
//函式說明:獲得檔案節點的下一個檔案節點
//引數1: 當前檔案節點
//引數2: 下一個檔案的資訊結構體 out型
//返回值: 下一個檔案節點
通過以上兩個函式配合,從碟符開始,通過do...while() 迴圈可得到遍歷檔案
RunFile()
函式原型:int RunFile();
函式功能:執行本地檔案,通過資料包中的路徑,執行檔案
內部使用主要系統函式:
HINSTANCE ShellExecute(HWND hwnd, LPCSTR lpOperation, LPCSTR lpFile, LPCSTR lpParameters, LPCSTR lpDirectory, INT nShowCmd)
//函式說明:執行指定檔案
//引數1:視窗控制程式碼 這裡填NULL,表示不指定父視窗
//引數2:用於指定進行的操作,當為NULL時,表示預設開啟
//引數3:可執行檔案完整路徑
//引數4:可執行檔案的命令列,這裡設定為NULL
//引數5:指定預設目錄
//引數6:初始化顯示方式,模擬正常開啟檔案使用 SW_SHOWNORMAL
返回值:執行成功會返回應用程式控制程式碼
DownloadFile()
函式原型:int DownloadFile()
函式說明:下載檔案,獲取資料包中的路徑,使用檔案操作函式讀取檔案到緩衝區,並打包傳送回客戶端。
內部使用的主要系統函式:
- errno_t fopen_s( FILE** pFile, const char *filename, const char *mode );
//函式說明:以某種方式開啟指定檔案
//引數1:檔案指標out型,
//引數2:檔案路徑
//引數3:開啟方式,這裡以二進位制讀的方式開啟,為 ”rb”
//返回值:成功返回0,失敗返回錯誤碼 - int fseek(FILE *stream, long offset, int fromwhere);
//函式說明:設定檔案指標stream的位置
//引數1:檔案指標
//引數2:偏移,這裡填空或者0
//引數3:將檔案指標指向某個位置,SEEK_SET表示指向檔案頭,SEEK_END表示指向檔案尾
//返回值: 成功返回0,失敗返回非0值,並設定error的值,可以用perror()函式輸出錯誤。 - size_t fread(void* buffer,size_t size,size_t count,FILE* stream);
//函式說明:將檔案指標指向的資料以資料流的方式讀取到目標緩衝區
//引數1:指定的緩衝區
//引數2:一次讀取的寬度
//引數3,讀取的次數
//引數4:檔案流
//返回值:返回成功讀取的物件個數,若出現錯誤或到達檔案末尾,則可能小於count。
MouseEvent()
函式原型:int MouseEvent();
函式說明:處理滑鼠操作
//成功返回0,失敗返回-1
內部使用的系統函式:
- BOOL SetCursorPos(int X,int Y);
//函式說明:設定滑鼠座標
//引數1:滑鼠x座標
//引數2:滑鼠y座標
//返回值:如果成功,返回非零值;如果失敗,返回值是零,可呼叫GetLastError()得到詳細資訊 - WIN系統 mouse_event(DWORD dwFlags,DWORD dx,DWORD,dy,DWORD dwData,ULONG_PTR dwExtraInfo);
//函式說明:滑鼠響應事件
//引數1:滑鼠動作,如點選、雙擊、左鍵、右鍵等
//引數2:滑鼠x座標
//引數3:滑鼠y座標
//引數4:滑鼠輪滑,正數向前滑,負數向後滑,當dwFlags為輪滑操作時候才設定,一般為0
//引數5,指定與滑鼠事件相關的值,呼叫GetMessageExtraInfo()來得到
//返回值:
MouseEvent結構體
說明:設計一個滑鼠資訊的資料結構,用於接收客戶端滑鼠操作命令
nButton:0表示左鍵,1表示右鍵,2表示中鍵,4沒有按鍵
nAction: 0表示單擊,1表示雙擊,2表示按下,3表示放開,4不作處理
SendScreen()
函式原型:int SendScreen();
函式說明:遠端桌面,採用圖傳功能實現
內部使用的函式:
- HDC GetDC(HWND hWnd);
//功能作用:檢索指定視窗的客戶區的顯示上下文環境控制程式碼
//引數1:指定視窗控制程式碼
//返回值:返回值表示指定視窗區域的DC控制程式碼,失敗返回NULL - int GetDeviceCaps(HDC hdc,LPRECT lprect);
//函式功能:獲取DC的指定資料
//引數1:指定的HDC控制程式碼
//引數2:指定定資料。BITSPIXEL:畫素相連顏色位數, HORZRES:寬, VERTRES:高
//返回值:int資料
LockMachine()
函式原型:int LockMachine();
函式說明:鎖機,通過建立執行緒,讓執行緒建立大於整個螢幕的對話方塊,阻擋滑鼠點選操作,並將滑鼠固定在一個位置,另外做一個訊息迴圈,用於恢復鎖機。暫時未實現鎖定鍵盤操作。
內部使用的函式操作:
鎖定滑鼠功能實現:
- ShowCursor(BOOL bShow); //游標操作
- ::ShowWindow(HWND hWnd, int nCmdShow); //隱藏或顯示視窗
- ClipCursor(RECT *lpRect); //設定滑鼠座標
- BOOL GetMessage(LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax)
//函式說明:從訊息佇列中取資料,本次功能中此處用於解鎖。
//引數1:訊息結構體指標,用於存放取得的資料
//引數2:取得訊息的視窗控制程式碼
//引數3:指定被檢索的最小訊息值的整數,一般用於訊息過濾,為0時,無過濾
//引數4:指定被檢索的最大訊息值的整數,一般用於訊息過濾,為0時,無過濾
//返回值
UnLockMachine()
函式原型:int UnLockMachine();
函式功能:解鎖,向鎖機執行緒傳送post訊息
內部使用的系統函式:
- BOOL PostThreadMessage(DWORD idThread, UINT Msg, WPARAM wParam, LPARAM lParam)
//功能作用:將訊息傳送到指定執行緒的訊息佇列裡
//引數1:指定的執行緒id
//引數2:指定的訊息型別
//引數3:訊息w,一般是一些常量值
//引數4:訊息l,一般是傳指標
//返回值:如果函式呼叫成功,返回非零值。如果函式呼叫失敗,返回值是零。
DeleteLocalFile()
函式原型:int DeleteLocalFile();
函式功能:刪除指定檔案
//返回值:成功返回0,失敗返回非0值
內部使用的函式:
- BOOL DeleteFile(LPCWSTR lpFileName)
//功能作用:刪除指定檔案,測試刪除為永久刪除,不放入回收站,需要呼叫者的許可權足夠
//引數1:指定檔案路徑的指標
//返回值:成功返回0,失敗返回非0值
相關文章
- 遠端終端服務的簡單實現
- bbossaop遠端服務介紹-遠端服務呼叫例項
- bbossaop遠端服務介紹-遠端服務id定義規則
- 實現SSR服務端渲染服務端
- golang實現tcp客戶端服務端程式GolangTCP客戶端服務端
- React 服務端渲染實現 Gank 移動端React服務端
- 本地除錯遠端服務除錯
- 實現ssr服務端渲染demo服務端
- VNC遠端控制,VNC遠端控制連線WindowsVNCWindows
- Android實現Thrift服務端與客戶端Android服務端客戶端
- bbossaop遠端服務介紹-點對點遠端服務呼叫和組播服務呼叫的區別
- dubbo 遠端服務無法呼叫
- spring 的遠端服務是?Spring
- Windows遠端連線Docker服務WindowsDocker
- C# 之 服務端獲取遠端資源C#服務端
- Go實現ssh執行遠端命令及遠端終端Go
- React + Koa 實現服務端渲染(SSR)React服務端
- 實現客戶端與服務端的HTTP通訊客戶端服務端HTTP
- spring cloud feign實現遠端呼叫服務傳輸檔案SpringCloud
- win10 如何開啟遠端服務_win10如何開啟遠端連線服務Win10
- 如何在命令列下遠端安裝終端服務命令列
- 命令列重啟遠端桌面服務命令列
- Linux下 SSH遠端管理服務Linux
- 記一次實現遠端控制電腦開機過程
- mysql實現遠端訪問,phpmyadmin實現遠端連線mysqlMySqlPHP
- Qt實現網路聊天室(客戶端,服務端)QT客戶端服務端
- 遠端控制篇:抓取遠端螢幕影像 (轉)
- 利用WebSocket和EventSource實現服務端推送Web服務端
- React服務端渲染實現(基於Dva)React服務端
- [譯]React在服務端渲染的實現React服務端
- [譯] React 在服務端渲染的實現React服務端
- 自建服務端實現Tinker熱修復服務端
- 使用java登入遠端LINUX並對服務實現各種操作JavaLinux
- NAS教程丨如何透過DDNS實現SMB服務的遠端訪問?DNS
- hubilder打包+C#服務端個推服務實現C#服務端
- FRP+WoL實現遠端開機+遠端桌面FRP
- 5分鐘搞定 服務端 本地開發 遠端執行服務端
- 快速實現無人車遠端控制開發——實踐類