网络编程——基于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;
}

运行效果:

附件:源码(客户端和服务器)

时间: 2024-08-05 19:58:28

网络编程——基于UDP的网络化CPU性能检测的相关文章

Java网络编程 - 基于UDP协议 实现简单的聊天室程序

最近比较闲,一直在抽空回顾一些Java方面的技术应用. 今天没什么事做,基于UDP协议,写了一个非常简单的聊天室程序. 现在的工作,很少用到socket,也算是对Java网络编程方面的一个简单回忆. 先看一下效果: 实现的效果可以说是非常非常简单,但还是可以简单的看到一个实现原理. "聊天室001"的用户,小红和小绿相互聊了两句,"聊天室002"的小黑无人理会,在一旁寂寞着. 看一下代码实现: 1.首先是消息服务器的实现,功能很简单: 将客户端的信息(进入了哪一个聊

JAVA基础知识之网络编程——-基于UDP协议的通信例子

UDP是一种不可靠的协议,它在通信两端各建立一个socket,这两个socket不会建立持久的通信连接,只会单方面向对方发送数据,不检查发送结果. java中基于UDP协议的通信使用DatagramSocket类的receive和send方法即可,但消息需要通过一个特定的类封装(DatagramPacket) 下面是一个基于UDP协议的通信的例子, 服务器端, 1 package udp; 2 3 import java.io.IOException; 4 import java.net.Dat

网络编程: 基于UDP协议的socket

udp是无链接的,启动服务之后可以直接接受消息,不需要提前建立链接 UDP协议的通信优势: 允许一个服务器同时和多个客户端通信, TCP不行 原文地址:https://www.cnblogs.com/niuli1987/p/9470035.html

java 网络编程 基于UDP协议的通信

使用UDP协议,写一个能在同一界面发送消息,并显示消息的聊天软件. 代码实现如下: package com.abel.socket; import java.io.IOException;import java.net.DatagramPacket;import java.net.DatagramSocket;import java.net.InetAddress;import java.util.Scanner; /* * 多线程在一个界面同时完成发送接收 * 1 发送send * ***创建

linux网络编程笔记——UDP

目前这部分代码会出现阻塞问题,暂时尚未解决 #include "udp.h" #include <stdio.h> #include <string.h> #include <stdlib.h> #include <unistd.h> #include <errno.h> #include <malloc.h> #include <sys/types.h> #include <sys/socket

Java网络编程(UDP程序设计)

//客户端 package org.udp; import java.net.DatagramPacket; import java.net.DatagramSocket; public class UDPClient { public static void main(String[] args) throws Exception{ DatagramSocket ds = null; byte[] buf = new byte[2014]; DatagramPacket dp = null;

网络编程——基于TCP协议的Socket编程,基于UDP协议的Socket编程

Socket编程 目前较为流行的网络编程模型是客户机/服务器通信模式 客户进程向服务器进程发出要求某种服务的请求,服务器进程响应该请求.如图所示,通常,一个服务器进程会同时为多个客户端进程服务,图中服务器进程B1同时为客户进程A1.A2和B2提供服务. Socket概述 ①   所谓Socket通常也称作“套接字”,用于描述IP地址和端口,是一个通信链的句柄.应用程序通常通过“套接字”向网络发出请求或者应答网络请求. ②   Socket是连接运行在网络上的两个程序间的双向通信的端点. ③  

linux网络编程 基于TCP的程序开发

面向连接的TCP程序设计 基于TCP的程序开发分为服务器端和客户端两部分,常见的核心步骤和流程: 其实按照上面这个流程调用系统API确实可以完全实现应用层程序的开发,一点问题没有.可随着时间的推移,你会觉得这样子的开发毫无激情.为什么TCP的开发就要按照这样的流程来呢?而且一般出的问题几乎都不在这几个系统调用上,原因何在?当我们弄清网络开发的本质,协议栈的设计原理.数据流向等这些问题的答案也就会慢慢浮出水面了.接下来这几篇博文主要是围绕网络编程展开,目的是引出后面对于Linux下TCP/IP协议

--------------------------------------网络编程(UDP)

InetAddress类java.net包中的InetAddress类用于封装IP地址和DNS.要创建InetAddress类的实例.可以使用工厂方法,因为此类没有可用的的构造方法.InetAddress类中的工厂方法static InetAddress getLocalHost();//返回表示本机InetAddress对象static InetAddress getByName(String hostName);//为主机名为hostName的主机返回InetAddress对象static