1. 程式人生 > >網絡編程——基於UDP的網絡化CPU性能檢測

網絡編程——基於UDP的網絡化CPU性能檢測

ldb img set cmem accep count() mco dot cas

網絡化計算機性能檢測軟件的開發,可對指定目標主機的CPU利用率進行遠程檢測,並自動對遠程主機執行性能指標進行周期性檢測,最終實現圖形化顯示檢測結果。

技術分享

網絡通信模塊:(客戶端類似,因為udp是對等通信)

啟動服務器:創建套接字並註冊網絡事件
void CRemoteCPUImitateDlg::OnBnClickedOk()
{
    // TODO: 在此添加控件通知處理程序代碼
    int     Ret;
    char    BufferData[2000] = { 0 };
    int     ClientAddrSize = sizeof(ClientAddress);
    GetDlgItem(IDOK)
->EnableWindow(FALSE); memset(BufferData, 0, sizeof(BufferData)); ServerAddress.sin_port = htons(4440); ServerAddress.sin_family = AF_INET; ServerAddress.sin_addr.s_addr = INADDR_ANY; //初始化本地網卡 m_ServerSocket = WSASocket(AF_INET, SOCK_DGRAM, 0, NULL, 0, 0); if (m_ServerSocket == SOCKET_ERROR) { MessageBox(L
"創建套接字失敗!"); return ; } int Result = bind(m_ServerSocket, (sockaddr*)&ServerAddress, sizeof(ServerAddress)); if (Result != 0) { int a = GetLastError(); MessageBox(L"綁定套接字失敗!"); return; } if (WSAAsyncSelect(m_ServerSocket, m_hWnd, UM_RECV, FD_ALL_EVENTS)) { MessageBox(L
"註冊網絡讀取事件失敗!"); return; } } 網絡事件響應函數 afx_msg LRESULT CRemoteCPUImitateDlg::OnUmRecv(WPARAM wParam, LPARAM lParam) { int Ret; int i; memset(BufferData, 0, sizeof(BufferData)); int ClientAddrSize = sizeof(ClientAddress); memset(&ClientAddress, 0, sizeof(ClientAddress)); if (WSAGETSELECTERROR(lParam)) { return false; } else { switch (WSAGETSELECTEVENT(lParam)) { case FD_ACCEPT://接受客戶端連接請求。 { MessageBox(L"FD_ACCEPT"); } break; case FD_READ://可讀,接收數據。 { if ((Ret = recvfrom(m_ServerSocket, BufferData, 2000, 0, (SOCKADDR *)&ClientAddress, &ClientAddrSize)) == SOCKET_ERROR) { //MessageBox(L"接受數據失敗"); closesocket(m_ServerSocket); return 0; } else { BYTE bToken = (BYTE)BufferData[0]; switch (bToken) { case 1://登錄 { LOGIN_INFORMATION* li = (LOGIN_INFORMATION*)BufferData; CString str,strIP, strAddr, strPCName, strOS, strCPU, strPing; int ClientLength = sizeof(sockaddr_in); strIP = inet_ntoa(ClientAddress.sin_addr); for (i = 0; i < m_ListUser.GetItemCount(); i++) { str = m_ListUser.GetItemText(i, 0); if (str == strIP) { MessageBox(L"該用戶已在線!"); return 0; } } //主機名稱 strPCName = li->PCName; switch (li->OsVerInfoEx.dwPlatformId) { case VER_PLATFORM_WIN32_NT: if (li->OsVerInfoEx.dwMajorVersion <= 4) strOS = "WindowsNT"; if (li->OsVerInfoEx.dwMajorVersion == 5 && li->OsVerInfoEx.dwMinorVersion == 0) strOS = "Windows2000"; if (li->OsVerInfoEx.dwMajorVersion == 5 && li->OsVerInfoEx.dwMinorVersion == 1) strOS = "WindowsXP"; if (li->OsVerInfoEx.dwMajorVersion == 5 && li->OsVerInfoEx.dwMinorVersion == 2) strOS = "Windows2003"; if (li->OsVerInfoEx.dwMajorVersion == 6 && li->OsVerInfoEx.dwMinorVersion == 0) strOS = "WindowsVista"; if (li->OsVerInfoEx.dwMajorVersion == 6 && li->OsVerInfoEx.dwMinorVersion == 1) strOS = "Windows7"; if (li->OsVerInfoEx.dwMajorVersion == 6 && li->OsVerInfoEx.dwMinorVersion == 2) strOS = "Windows10"; } //CPU strCPU.Format(L"%dMHz", li->CPUMHz); //網速 strPing.Format(L"%d", li->Speed); AddList(strIP, strPCName, strOS, strCPU, strPing); break; } case 2://cpu信息 { sumCpu = (UINT)BufferData[sizeof(BYTE)]; if (Dlg == NULL) { return 0; } Dlg->m_sumCpu = sumCpu; WPARAM a; a = sumCpu; ::PostMessage(Dlg->GetSafeHwnd(), UM_CHANGE, a, 0); break; } case 3://下線 { CString strIP, str; strIP = inet_ntoa(ClientAddress.sin_addr); for (i = 0; i < m_ListUser.GetItemCount() ; i++) { str = m_ListUser.GetItemText(i, 0); if (str == strIP) { m_ListUser.DeleteItem(i); } } break; } default: break; } } //在新接受的套接字發生FD_READ,FD_WRITE,FD_CLOSE網絡事件發生,發送WM_SOCKET消息; //WSAAsyncSelect(sAccept, this->m_hWnd, UM_RECV, FD_READ | FD_WRITE | FD_CLOSE); } break; case FD_WRITE://可寫,發送數據。 { //MessageBox(L"FD_WRITE"); } break; case FD_CLOSE://對方關閉套接字連接。 { if (WSAGETSELECTERROR(lParam) == 0) { //從容關閉。 } else if (WSAGETSELECTERROR(lParam) == WSAECONNREFUSED) { //硬關閉。 } } break; default: break; } } return 0; }

CPU圖像繪制模塊:(參考了網上的代碼)

繪制CPU使用率進度條
UINT CDisplayDlg::DoSysCpu(LPVOID pParam)
{
    CDisplayDlg *pthis = (CDisplayDlg *)pParam;
    CString showCpu;
    UINT sumCpu = 0;
    if (bFirst)
    {
        bFirst = FALSE;
        m_sumCpu = 1;
    }
    else
    {
        sumCpu = m_sumCpu;
    }
    
        sumCpu = sumCpu % 101;
        pthis->m_Process_CPU.SetPos(sumCpu);
        showCpu.Format(L"%u %%", sumCpu);
        pthis->GetDlgItem(IDC_STATIC_CPU)->SetWindowText(showCpu);
                pthis->UpdateWindow();
        pthis->Invalidate(FALSE);
        ::PostMessage(pthis->GetSafeHwnd(), WM_PAINT, 0, 0);
    return 0;
}
4.5 繪制CPU使用記錄折線
BOOL CDisplayDlg::CDrawCpu(CDC *pDC)
{
    CRect rect;
    GetDlgItem(IDC_SHOWCPU)->GetClientRect(&rect);
    CDC dcMem; //用於緩沖作圖的內存DC 
    CBitmap bmp; //內存中承載臨時圖象的位圖 
    CBitmap *oldBmp;
    dcMem.CreateCompatibleDC(pDC); //依附窗口DC創建兼容內存DC 

    bmp.CreateCompatibleBitmap(pDC, rect.Width(), rect.Height());//創建兼容位圖 

    oldBmp = dcMem.SelectObject(&bmp); //將位圖選擇進內存DC 

    int i = 1;
    //繪圖

    //背景

    dcMem.FillSolidRect(rect, RGB(222, 222, 222));

    CPen pen;
    if (!pen.CreatePen(PS_DOT, 1, RGB(255, 255, 255)))
    {
        return FALSE;
    }

    CPen *pOldPen = dcMem.SelectObject(&pen);//保存舊畫筆

                                             //橫線
    for (i = 1; i < 10; i++)
    {
        dcMem.MoveTo(0, rect.Height()*i / 10);
        dcMem.LineTo(rect.Width(), rect.Height()*i / 10);
    }


    //豎線
    for (i = 1; i < 30; i++)
    {
        dcMem.MoveTo(rect.Width()*i / 30, 0);
        dcMem.LineTo(rect.Width()*i / 30, rect.Height());
    }


    //收回資源並釋放
    dcMem.SelectObject(pOldPen);
    pen.DeleteObject();


    //繪制四邊(防止閃爍)

    dcMem.MoveTo(0, 0);
    dcMem.LineTo(rect.Width(), 0);

    dcMem.MoveTo(0, rect.Height() - 1);
    dcMem.LineTo(rect.Width(), rect.Height() - 1);

    dcMem.MoveTo(0, 0);
    dcMem.LineTo(0, rect.Height());

    dcMem.MoveTo(rect.Width() - 1, 0);
    dcMem.LineTo(rect.Width() - 1, rect.Height());

    //繪制CPU運行狀態線
    if (!pen.CreatePen(0, 2, RGB(0, 200, 0)))
    {
        return FALSE;
    }

    pOldPen = dcMem.SelectObject(&pen);//保存舊畫筆

    pointCpu[0].x = rect.Width();
    pointCpu[0].y = rect.Height() - rect.Height()*m_sumCpu / 100;

    for (i = m_nMovNum; i > 0; i--)
    {
        if (i > 1)
        {
            dcMem.MoveTo(pointCpu[i - 2]);
            dcMem.LineTo(pointCpu[i - 1]);
        }

        pointCpu[i].x = pointCpu[i - 1].x - rect.Width() / maxpix - 1;
        pointCpu[i].y = pointCpu[i - 1].y;

    }

    dcMem.SelectObject(pOldPen);
    pen.DeleteObject();
    pOldPen = NULL;

    //將內存DC上的圖象拷貝到前臺 
    pDC->BitBlt(0, 0, rect.Width(), rect.Height(),

        &dcMem, 0, 0, SRCCOPY);

    //釋放資源
    dcMem.SelectObject(oldBmp);
    dcMem.DeleteDC(); //刪除DC
    bmp.DeleteObject(); //刪除位圖

    return TRUE;
}

運行效果:

技術分享

技術分享

技術分享

附件:源碼(客戶端和服務器)

網絡編程——基於UDP的網絡化CPU性能檢測