首页 > 代码库 > 网络编程——基于UDP的网络化CPU性能检测

网络编程——基于UDP的网络化CPU性能检测

网络化计算机性能检测软件的开发,可对指定目标主机的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性能检测