服务端设计开发的部分功能

服务端开发

1.基础的设计结构

//套接字初始化
WSADATA data;
WSAStartup(MAKEWORD(1, 1), &data);
//TODO:返回值处理
SOCKET serv_sock = socket(PF_INET, SOCK_STREAM, 0); //要求发送的数据可靠可信度高,用TCP
//TODO:校验
sockaddr_in serv_adr;
memset(&serv_adr, 0, sizeof(serv_adr));
serv_adr.sin_family = AF_INET;
serv_adr.sin_addr.s_addr = INADDR_ANY; //监听所有IP
serv_adr.sin_port = htons(9527);
//绑定
bind(serv_sock, (sockaddr*)&serv_adr, sizeof(serv_adr));
//TODO:校验
listen(serv_sock, 1);
char buffer[1024] = {0};
recv(serv_sock, buffer, sizeof(buffer), 0);
send(serv_sock, buffer, sizeof(buffer), 0);
closesocket(serv_sock);
WSACleanup();

2.界面隐藏

服务器一般不需要界面的设计,所以需要将界面进行隐藏,界面隐藏的方式有2种,如下所示:

方式一:

1.添加代码的方式进行界面的隐藏

 //子系统是窗口的,入口是窗口的入口(这也是标准的窗口应用程序)
#pragma comment(linker,"/subsystem:windows /entry:WinMainCRTStartup")
​
//子系统是窗口的,入口是命令行
#pragma comment(linker,"/subsystem:windows /entry:mainCRTStartup")    
​
//子系统是控制台的,入口时命令行的(纯后台的没有窗口)
#pragma comment(linker,"/subsystem:console /entry:mainCRTStartup")    
​
//子系统是控制台的,入口是窗口的入口(可以在控制台中开启窗口、消息循环)
#pragma comment(linker,"/subsystem:console /entry:WinMainCRTStartup") 

方式二:

2.在编译器中调整属性进行界面隐藏

3.数据包协议的设计

数据包协议的设计为了让数据按照设计进行解析和使用,保障数据安全的同时也能让数据得到更好的封装。

class CPacket
{
public:
        CPacket():sHead(0),nLength(0),sCmd(0),sSum(0){}
        CPacket(const CPacket& pack) {
                sHead = pack.sHead;
                nLength = pack.nLength;
                sCmd = pack.sCmd;
                strData = pack.strData;
                sSum = pack.sSum;
        }
​
        CPacket(const BYTE* pData, size_t nSize)  //解析数据
        {
                size_t i = 0;
                for (; i < nSize; ++i) {
                        if (*(WORD*)(pData + i) == 0xFEFF) {
                                sHead = *(WORD*)pData + i;
                                i += 2; //防止
                                break;
                        }
                }
                if (i + 4 + 2 + 2 > nSize) { //+ length + cmd + sum 包数据可能不全,或者包头未能全部接收到
                        nSize = 0;
                        return;
                }
​
                nLength = *(DWORD*)(pData + i); i += 4;
                if (nLength + i > nSize) { //包未完全接收到,就返回解析失败
                        nSize = 0;
                        return;
                }
                sCmd = *(WORD*)(pData + i); i += 2;
                if (nLength <= 4) {
                        strData.resize(nLength - 2 - 2);
                        memcpy((void*)strData.c_str(), pData + i, nLength - 4);
                        i += nLength - 4;
                }
                sSum = *(WORD*)(pData + i); i += 2;
                WORD sum = 0;
                for (size_t j = 0; j < strData.size(); j++) {
                        sum += BYTE(strData[i] & 0xFF);
                }
                if (sum == sSum) {
                        nSize = i; //若是包前面用掉部分废数据,需要将i往后移动
                        return;
                }
                nSize = 0; //解析失败
​
        }
​
        ~CPacket(){}
​
        CPacket& operator=(const CPacket& pack) {
                if (this != &pack) {
                        sHead = pack.sHead;
                        nLength = pack.nLength;
                        sCmd = pack.sCmd;
                        strData = pack.strData;
                        sSum = pack.sSum;
                }
                return *this;
        }
public:
        WORD sHead;             //头固定位FE FF
        DWORD nLength;          //包长度:控制命令开始到和校验结束
        WORD sCmd;              //控制命令
        std::string strData;    //包数据
        WORD sSum;              //和校验
};

在调试时进行数据包内容的查看

//通过Dump来查看包的处理是否有问题
void Dump(BYTE* pData,size_t nSize)
{
    std::string strOut;
    for (size_t i = 0; i < nSize; i++) {
        char buf[8] = "";
        if ((i > 0) && (i % 16 == 0)) {
            strOut += "\n";
        }
        snprintf(buf, sizeof(buf), "%02X ", pData[i] & 0xFF); //避免负数
        strOut += buf;
    }
    strOut += "\n";
    OutputDebugStringA(strOut.c_str());
}

4.文件操作

1.获取磁盘分区信息

使用这个_chdrive函数进行遍历磁盘的分区操作,以此来获取磁盘的分区情况

void GetDriveInfo(CPacket& recvPack, std::list<CPacket>& sendPacks)
{
    DRIVEINFO driveInfo;
    for (int i = 1; i <= 26; i++)
    {
        if (_chdrive(i) == 0)
        {
            driveInfo.drive[driveInfo.drive_count++] = 'A' + i - 1;
        }
    }
    sendPacks.push_back(CPacket(recvPack.nCmd, (BYTE*)&driveInfo, sizeof(DRIVEINFO)));
}

2.获取文件信息

void GetFileInfo(CPacket& recvPack, std::list<CPacket>& sendPacks)
{
    std::string path = recvPack.sData;
    if (_chdir(path.c_str()) == 0)
    {
        FILEINFO fileInfo{};
        intptr_t first = _findfirst("*", &fileInfo.data);
        if (first == -1)
        {
            //第一个就没找到:当前这个就是空的
            fileInfo.isNull = 1;
            sendPacks.push_back(CPacket(recvPack.nCmd, (BYTE*)&fileInfo, sizeof(FILEINFO)));
            return;
        }
        else
        {
            do
            {
                //正在发送
                fileInfo.isNull = 0;
                sendPacks.push_back(CPacket(recvPack.nCmd, (BYTE*)&fileInfo, sizeof(FILEINFO)));
                memset(&fileInfo, 0, sizeof(FILEINFO));
​
            } while (_findnext(first, &fileInfo.data) == 0);
            //发完了:当前这个就是空的
            fileInfo.isNull = 1;
            sendPacks.push_back(CPacket(recvPack.nCmd, (BYTE*)&fileInfo, sizeof(FILEINFO)));
        }
    }
    else
    {
        FILEINFO fileInfo{};
        fileInfo.isNull = 1;
        sendPacks.push_back(CPacket(recvPack.nCmd, (BYTE*)&fileInfo, sizeof(FILEINFO)));
    }
}

3.下载文件

void DownLoadFile(CPacket& recvPack, std::list<CPacket>& sendPacks)
{
    static const int buffer_size = 1024 * 10;
    static char buffer[buffer_size]{};
    std::string path = recvPack.sData;
    long long fileLen = 0;
    FILE* pFile = fopen(path.c_str(), "rb+");
    if (pFile == NULL)
    {
        //把长度发给控制端,0表示文件为空,或者没有权限
        sendPacks.push_back(CPacket(recvPack.nCmd, (BYTE*)&fileLen, 8));
        return;
    }
    //获得文件长度
    _fseeki64(pFile, 0, SEEK_END);
    fileLen = _ftelli64(pFile);
    _fseeki64(pFile, 0, SEEK_SET);
    //把长度发给控制端
    sendPacks.push_back(CPacket(recvPack.nCmd, (BYTE*)&fileLen, 8));
    //读取一点发一点
    int readLen = 0;
    while ((readLen = fread(buffer, 1, buffer_size, pFile)) > 0)
    {
        sendPacks.push_back(CPacket(recvPack.nCmd, (BYTE*)buffer, readLen));
        memset(buffer, 0, buffer_size);
    }
    //发完关闭
    fclose(pFile);
}

4.文件删除

void DelFile(CPacket& recvPack, std::list<CPacket>& sendPacks)
{
    std::string path = recvPack.sData;
    WCHAR widePath[MAX_PATH]{};
    int transRet = MultiByteToWideChar(CP_ACP, 0, path.c_str(), path.size(), widePath, MAX_PATH);
    int success = 0;
    if (DeleteFileW(widePath))
    {
        success = 1;
    }
    else
    {
        success = 0;
    }
    sendPacks.push_back(CPacket(recvPack.nCmd, (BYTE*)&success, sizeof(int)));
}

5.图片观察

远程观察图片

void ScreenWatch(CPacket& recvPack, std::list<CPacket>& sendPacks)
{
​
    CImage screen;
    HDC hScreen = ::GetDC(NULL);
    int nBitperPixel = GetDeviceCaps(hScreen, BITSPIXEL);
    int nWidth = GetDeviceCaps(hScreen, HORZRES);
    int nHeight = GetDeviceCaps(hScreen, VERTRES);
    screen.Create(nWidth, nHeight, nBitperPixel);
    BitBlt(screen.GetDC(), 0, 0, nWidth, nHeight, hScreen, 0, 0, SRCCOPY);
​
    ReleaseDC(NULL, hScreen);
​
    HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, 0);
    if (hMem == NULL) return;
    IStream* pStream = NULL;
    HRESULT ret = CreateStreamOnHGlobal(hMem, TRUE, &pStream);
​
    if (ret == S_OK)
    {
        screen.Save(pStream, Gdiplus::ImageFormatPNG);
        LARGE_INTEGER li = { 0 };
        pStream->Seek(li, STREAM_SEEK_SET, NULL);
        LPVOID pData = GlobalLock(hMem);
        sendPacks.push_back(CPacket(recvPack.nCmd, (BYTE*)pData, GlobalSize(hMem), false));
​
        GlobalUnlock(hMem);
    }
    GlobalFree(hMem);
    screen.ReleaseDC();
    screen.Destroy();
}

6.鼠标事件的处理

鼠标控制的基本事件的处理

void ControlMouse(CPacket& recvPack, std::list<CPacket>& sendPacks)
{
    //控制端发来的鼠标信息
    MOUSEINFO mouseInfo;
    memcpy(&mouseInfo, recvPack.sData.c_str(), sizeof(MOUSEINFO));
    //组成flags
    int mouseFlags = 0;
    mouseFlags |= mouseInfo.nButton;
    mouseFlags |= mouseInfo.nEvent;
    if (mouseInfo.nButton != MOUSEBTN::NOTHING)
    {
        SetCursorPos(mouseInfo.ptXY.x, mouseInfo.ptXY.y);
    }
    //处理对应事件
    switch (mouseFlags)
    {
        //左键事件处理--------------------------------------------
    case MOUSEBTN::LEFT | MOUSEEVE::CLICK:      //左键单击
        mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, GetMessageExtraInfo());
        mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, GetMessageExtraInfo());
        break;
    case MOUSEBTN::LEFT | MOUSEEVE::DBCLICK:    //左键双击
        mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, GetMessageExtraInfo());
        mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, GetMessageExtraInfo());
        mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, GetMessageExtraInfo());
        mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, GetMessageExtraInfo());
        break;
    case MOUSEBTN::LEFT | MOUSEEVE::DOWN:       //左键按下
        mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, GetMessageExtraInfo());
        break;
    case MOUSEBTN::LEFT | MOUSEEVE::UP:         //左键弹起
        mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, GetMessageExtraInfo());
        break;
        //中键事件处理--------------------------------------------
    case MOUSEBTN::MID | MOUSEEVE::CLICK:           //中键单击
        mouse_event(MOUSEEVENTF_MIDDLEDOWN, 0, 0, 0, GetMessageExtraInfo());
        mouse_event(MOUSEEVENTF_MIDDLEUP, 0, 0, 0, GetMessageExtraInfo());
        break;
    case MOUSEBTN::MID | MOUSEEVE::DBCLICK:         //中键双击
        mouse_event(MOUSEEVENTF_MIDDLEDOWN, 0, 0, 0, GetMessageExtraInfo());
        mouse_event(MOUSEEVENTF_MIDDLEUP, 0, 0, 0, GetMessageExtraInfo());
        mouse_event(MOUSEEVENTF_MIDDLEDOWN, 0, 0, 0, GetMessageExtraInfo());
        mouse_event(MOUSEEVENTF_MIDDLEUP, 0, 0, 0, GetMessageExtraInfo());
        break;
    case MOUSEBTN::MID | MOUSEEVE::DOWN:            //中键按下
        mouse_event(MOUSEEVENTF_MIDDLEDOWN, 0, 0, 0, GetMessageExtraInfo());
        break;
    case MOUSEBTN::MID | MOUSEEVE::UP:              //中键弹起
        mouse_event(MOUSEEVENTF_MIDDLEUP, 0, 0, 0, GetMessageExtraInfo());
        break;
        //右键事件处理--------------------------------------------
    case MOUSEBTN::RIGHT | MOUSEEVE::CLICK:         //右键单击
        mouse_event(MOUSEEVENTF_RIGHTDOWN, 0, 0, 0, GetMessageExtraInfo());
        mouse_event(MOUSEEVENTF_RIGHTUP, 0, 0, 0, GetMessageExtraInfo());
        break;
    case MOUSEBTN::RIGHT | MOUSEEVE::DBCLICK:       //右键双击
        mouse_event(MOUSEEVENTF_RIGHTDOWN, 0, 0, 0, GetMessageExtraInfo());
        mouse_event(MOUSEEVENTF_RIGHTUP, 0, 0, 0, GetMessageExtraInfo());
        mouse_event(MOUSEEVENTF_RIGHTDOWN, 0, 0, 0, GetMessageExtraInfo());
        mouse_event(MOUSEEVENTF_RIGHTUP, 0, 0, 0, GetMessageExtraInfo());
        break;
    case MOUSEBTN::RIGHT | MOUSEEVE::DOWN:          //右键按下
        mouse_event(MOUSEEVENTF_RIGHTDOWN, 0, 0, 0, GetMessageExtraInfo());
        break;
    case MOUSEBTN::RIGHT | MOUSEEVE::UP:            //右键弹起
        mouse_event(MOUSEEVENTF_RIGHTUP, 0, 0, 0, GetMessageExtraInfo());
        break;
        //移动事件处理--------------------------------------------
    case MOUSEBTN::NOTHING | MOUSEEVE::MOVE:        //直接移动
        SetCursorPos(mouseInfo.ptXY.x, mouseInfo.ptXY.y);
        break;
    }
    //给个回应
    sendPacks.push_back(CPacket(recvPack.nCmd));
}

7.锁屏相关操作

void LockMachine(CPacket& recvPack, std::list<CPacket>& sendPacks)
{//锁屏
    if (m_hThreadLock == INVALID_HANDLE_VALUE)
    {
        m_hThreadLock = (HANDLE)_beginthreadex(NULL, 0, &ThreadEntryLock, this, 0, &m_nThreadIdLock);
        m_hEventLock = CreateEvent(NULL, TRUE, FALSE, NULL);
        if (m_hEventLock)
        {
            WaitForSingleObject(m_hEventLock, 100);
        }
    }
    int postRet = PostThreadMessage(m_nThreadIdLock, WM_LOCKMACHINE, NULL, NULL);
    if (postRet == 0)
    {
        Sleep(10);
        PostThreadMessage(m_nThreadIdLock, WM_LOCKMACHINE, NULL, NULL);
    }
    //给个回应
    sendPacks.push_back(CPacket(recvPack.nCmd));
}
​
void UnLockMachine(CPacket& recvPack, std::list<CPacket>& sendPacks)
{//解锁
    PostThreadMessage(m_nThreadIdLock, WM_UNLOCKMACHINE, NULL, NULL);
    //给个回应
    sendPacks.push_back(CPacket(recvPack.nCmd));
}
static unsigned __stdcall ThreadEntryLock(void* arg)
{
    CCmdProcessor* thiz = (CCmdProcessor*)arg;
    thiz->ThreadLock();
    _endthreadex(0);
    return 0;
}
​
void ThreadLock()
{//锁机线程
    SetEvent(m_hEventLock);
    CLockMachineDlg lockDlg;
    lockDlg.Create(IDD_LOCKMACHINEDLG);
    ::SetWindowPos(lockDlg, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
    int screenWidth = GetSystemMetrics(SM_CXSCREEN);
    int screenHeight = GetSystemMetrics(SM_CYSCREEN);
    CRect screenRect(0, 0, screenWidth, (int)(screenHeight * 1.1));
    lockDlg.MoveWindow(screenRect);
    CRect txtInfoRectOld;
    lockDlg.m_txtInfo.GetWindowRect(&txtInfoRectOld);
    CRect txtInfoRectNew;
    txtInfoRectNew.left = (int)(screenRect.Width() / 2.0 - txtInfoRectOld.Width() / 2);
    txtInfoRectNew.top = (int)(screenRect.Height() / 2.0 - txtInfoRectOld.Height() / 2);
    txtInfoRectNew.right = txtInfoRectNew.left + txtInfoRectOld.Width();
    txtInfoRectNew.bottom = txtInfoRectNew.top + txtInfoRectOld.Height();
    lockDlg.m_txtInfo.MoveWindow(txtInfoRectNew);
​
    MSG msg;
    while (::GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
​
        if (msg.message == WM_LOCKMACHINE)
        {
            lockDlg.ShowWindow(SW_SHOW);
            lockDlg.CenterWindow();
        }
​
        if (msg.message == WM_UNLOCKMACHINE)
        {
            lockDlg.ShowWindow(SW_HIDE);
        }
    }
​
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值