網絡編程——基於UDP的網絡化CPU性能檢測
阿新 • • 發佈:2017-06-19
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性能檢測