• 利用Delphi实现网络监控系统


    实现的原理
    WINSOCK是一组API,用于在INTE.Net上传输数据和交换信息。用它编程本来是很麻烦的,但在DELPHHI中并不需要直接与WINSOCK的API打交道,因为TclientSocket和TserverSocket元件封装了它的大部分API,使得对WINSOCK的访问大大简化。
    SOCKET是网络通信的基本构件,是可以被命名和寻址的通信端点,使用中的第一个SOCKET都有其类型和一个与之相连的进程。SOCKET存在于通信区域中,通信区域也叫地址族,是一个抽象概念,主要用于将通过SOCKET通信线程的共有特性综合在一起。SOCKET通常只与同一区域中的SOCKET交换数据,也有可能跨区域通信,但这只是在执行了某种转换进程后才能实现。
    要通过网络传输数据,至少需要一对SOCKET。其中,一个SOCKET在客户端,另一个SOCKET在服务器端。一旦客户端和服务器端都接通了SOCKET,它们之间就可以相互通信,其连接是建立在TCP/IP协议基础上的,同时也支持其他相关协议,如XNS、DE.Net及IPX/SPX等。
    本系统就是基于上述原理的,它由两部分组成:驻留端和控制端。
    驻留端放在需要监控的机器上,WINDOWS启动时自动运行,并且要很好的隐藏起来:不出现的任务栏上,当用户按下CTRL+ALT+DEL时,也不能从任务列表中发现。
    控制端放在管理员的机器上,管理员通过指令可以观察或控制被监控的机器。指令有五个:
    截取屏幕:可以观察到被控机的当前屏幕,看操作员在干什么。
    远程关机:可以关闭被控的计算机。
    远程重启:可以重新启动被控的计算机。
    锁定机器:封锁被控机的操作,键盘、鼠标操作都无效。
    机器解锁:解除对被控机的封锁。
    代码编写
    1、 控制端
    主窗体设计如效果图,各控件名称如下表:

    名称 控件类型 标题 用途
    HscrollB TScrollBar; 滚动图像
    VScrollB TscrollBar 滚动图像
    Label1 Tlabel 显示文字
    Ipbox TcomboBox 显示IP地址列表
    RadioGroup1 TRadioGroup 美化界面
    Cuts TradioButton 截屏选择
    Cloma TradioButton 关机选择
    Restart TradioButton 启动选择
    Lock TradioButton 锁定选择
    Unlock TradioButton 解锁选择
    Button1 Tbutton 添加IP地址
    Button2 Tbutton 执行指令
    Button3 Tbutton 关闭界面
    Button4 Tbutton 连接监控端
    ImPanel TPanel 美化界面
    Image Timage 显示图像
    Panel1 TPanel 显示状态
    Kz TclientSocket 建立连接
    tccd TPopupMenu 弹出菜单

    控制端代码不太复杂,主要在为了显示从被监控机器传过来的数据时有点复杂,下面单独说明一下:
    procedure TForm1.kzRead(Sender: TObject; Socket: TCustomWinSocket);
    var buf:array[0..buffer-1] of char;//定义一个缓冲区,大小为2048字节
    temp:integer;
    begin
    temp:=socket.ReceiveLength;//得到传来数据的长度
    panel1.Caption:=‘正在接收来自‘+ipbox.Text+‘的图像数据,稍侯……‘;
    bmpmap.WriteBuffer(buf,Socket.ReceiveBuf(buf,temp));把缓冲区的数据写入流
    if temp<buffer then//如果数据长度小于缓冲区,说明数据已传完,显示图像
    begin
    bmpmap.Position:=0;
    ScrollReset;
    image.Picture.Bitmap.LoadFromStream(bmpmap);
    bmpmap.clear;
    panel1.Caption:=‘图像已经成功的接收!‘;
    end
    else Socket.SendText(‘cut‘);//否则继续要求传输
    end;
    在显示图像时,是通过滚动条和图像控件组合使用的,请注意代码
    当然,为了让软件更专业,要有托盘图标,这使代码复杂一些,这些功能在本系统中都实现了,请留意源代码。下面给出该系统的源代码:(代码容易看明白,不详细解释了)

    unit Unit1;

    interface

    uses
    Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
    StdCtrls, ExtCtrls, ComCtrls, ScktComp,shellapi, Menus;

    const wm_icb=wm_user+1000;
    type
    TForm1 = class(TForm)
    hScrollB: TScrollBar;
    vScrollB: TScrollBar;
    Label1: TLabel;
    ipbox: TComboBox;
    RadioGroup1: TRadioGroup;
    cuts: TRadioButton;
    cloma: TRadioButton;
    restart: TRadioButton;
    lock: TRadioButton;
    unlock: TRadioButton;
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    imPanel: TPanel;
    Image: TImage;
    Panel1: TPanel;
    kz: TClientSocket;
    Button4: TButton;
    tccd: TPopupMenu;
    N1: TMenuItem;
    N2: TMenuItem;
    N3: TMenuItem;
    N4: TMenuItem;
    N5: TMenuItem;
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure vScrollBChange(Sender: TObject);
    procedure hScrollBScroll(Sender: TObject; ScrollCode: TScrollCode;
    var ScrollPos: Integer);
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure Button4Click(Sender: TObject);
    procedure kzRead(Sender: TObject; Socket: TCustomWinSocket);
    procedure kzDisconnect(Sender: TObject; Socket: TCustomWinSocket);
    procedure kzConnect(Sender: TObject; Socket: TCustomWinSocket);
    procedure cutsClick(Sender: TObject);
    procedure clomaClick(Sender: TObject);
    procedure restartClick(Sender: TObject);
    procedure lockClick(Sender: TObject);
    procedure unlockClick(Sender: TObject);
    procedure kzConnecting(Sender: TObject; Socket: TCustomWinSocket);
    procedure kzError(Sender: TObject; Socket: TCustomWinSocket;
    ErrorEvent: TErrorEvent; var ErrorCode: Integer);
    procedure ipboxChange(Sender: TObject);
    procedure N3Click(Sender: TObject);
    procedure N2Click(Sender: TObject);
    procedure N1Click(Sender: TObject);
    private
    Units: TPoint;
    myicon:TNotifyicondata;
    procedure wmicb(var msg:TMessage);message wm_icb;
    procedure ScrollReset;
    { Private declarations }
    public
    { Public declarations }
    end;

    var
    Form1: TForm1;


    implementation

    uses Unit2, Unit3;

    {$R *.DFM}
    const
    DEF_SCROLL_UNITS = 8;
    buffer=2048;
    var bmpmap:TMemorystream;
    procedure display;
    begin
    if form1.visible=true then
    form1.n1.Caption:=‘显示(&D)‘
    else
    form1.n1.Caption:=‘隐藏(&H)‘;
    form1.visible:=not form1.visible;
    application.ShowMainForm:=form1.visible;
    setforegroundwindow(application.handle);
    end;

    procedure TForm1.Button2Click(Sender: TObject);
    begin
    display;
    end;


    procedure TForm1.Button3Click(Sender: TObject);

    begin
    if not assigned(form2) then form2:=Tform2.Create(application);
    form2.show;
    end;

    procedure TForm1.vScrollBChange(Sender: TObject);
    begin
    Image.Top := -Units.y * VScrollb.Position;
    end;

    procedure TForm1.hScrollBScroll(Sender: TObject; ScrollCode: TScrollCode;
    var ScrollPos: Integer);
    begin
    Image.Left := -Units.x * ScrollPos
    end;

    procedure TForm1.ScrollReset;
    begin
    Units.x := DEF_SCROLL_UNITS;
    Units.y := DEF_SCROLL_UNITS;
    if Image.Picture <> nil then
    begin
    Image.Top := 0;
    Image.Left := 0;
    HScrollb.Position := 0;
    VScrollb.Position := 0;
    HScrollb.Min := 0;
    VScrollb.Min := 0;
    HScrollb.Visible := True;
    VScrollb.Visible := True;
    end;
    end;

    procedure TForm1.Button1Click(Sender: TObject);
    begin
    if cuts.Checked then
    begin
    panel1.Caption:=‘截取‘+ipbox.Text+‘计算机的屏幕!‘;
    bmpmap.Clear;
    kz.Socket.SendText(‘cut‘);
    end
    else if cloma.Checked then
    begin
    panel1.Caption:=‘关闭‘+ipbox.Text+‘的计算机!‘;
    kz.Socket.SendText(‘ygj‘);
    kz.Active:=false;
    end
    else if restart.Checked then
    begin
    panel1.Caption:=‘重新启动‘+ipbox.Text+‘的计算机!‘;
    kz.Socket.SendText(‘yqd‘);
    kz.Active:=false;
    end
    else if lock.Checked then
    begin
    panel1.Caption:=‘锁定‘+ipbox.Text+‘的计算机!‘;
    kz.Socket.SendText(‘sdj‘);
    end
    else if unlock.Checked then
    begin
    panel1.Caption:=‘解锁‘+ipbox.Text+‘的计算机!‘;
    kz.Socket.SendText(‘jsj‘);
    end
    end;

    procedure TForm1.FormCreate(Sender: TObject);
    begin
    myicon.cbSize:=sizeof(TNotifyicondata);
    myicon.Wnd:=handle;
    myicon.uID:=1;
    myicon.uFlags:=nif_message or nif_tip or nif_icon;
    myicon.uCallbackMessage:=wm_icb;
    myicon.hIcon:=application.Icon.Handle;
    myicon.szTip:=‘大眼睛 V1.0‘;
    shell_notifyicon(nim_add,@myicon);
    setwindowlong(application.handle,gwl_exstyle,ws_ex_toolwindow);
    bmpmap:=TMemorystream.Create;
    ipbox.Items.LoadFromFile(‘pzwj.ini‘);
    end;

    procedure TForm1.FormDestroy(Sender: TObject);
    begin
    bmpmap.free;
    shell_notifyicon(nim_delete,@myicon);
    end;

    procedure TForm1.Button4Click(Sender: TObject);
    begin
    if ipbox.Text=‘‘ then exit;
    if button4.Caption=‘连接(&C)‘ then
    begin
    kz.Address:=ipbox.Text;
    kz.Active:=true;
    button1.Enabled:=true;
    end
    else
    begin
    kz.Active:=false;
    button1.Enabled:=false;
    end;
    end;
    procedure TForm1.kzRead(Sender: TObject; Socket: TCustomWinSocket);
    var buf:array[0..buffer-1] of char;
    temp:integer;
    begin
    temp:=socket.ReceiveLength;
    panel1.Caption:=‘正在接收来自‘+ipbox.Text+‘的图像数据,稍侯……‘;
    bmpmap.WriteBuffer(buf,Socket.ReceiveBuf(buf,temp));
    if temp<buffer then
    begin
    bmpmap.Position:=0;
    ScrollReset;
    image.Picture.Bitmap.LoadFromStream(bmpmap);
    bmpmap.clear;
    panel1.Caption:=‘图像已经成功的接收!‘;
    end
    else Socket.SendText(‘cut‘);
    end;

    procedure TForm1.kzDisconnect(Sender: TObject; Socket: TCustomWinSocket);
    begin
    button4.Caption:=‘连接(&C)‘;
    panel1.Caption:=‘已经和‘+ipbox.Text+‘断开连接‘;
    end;

    procedure TForm1.kzConnect(Sender: TObject; Socket: TCustomWinSocket);
    begin
    button4.Caption:=‘断开(&D)‘;
    panel1.Caption:=‘已经成功的连接到‘+ipbox.Text;
    end;

    procedure TForm1.cutsClick(Sender: TObject);
    begin
    panel1.Caption:=‘截取远程计算机的屏幕‘;
    end;

    procedure TForm1.clomaClick(Sender: TObject);
    begin
    panel1.Caption:=‘关闭远程计算机‘;
    end;

    procedure TForm1.restartClick(Sender: TObject);
    begin
    panel1.Caption:=‘重新启动远程计算机‘;
    end;

    procedure TForm1.lockClick(Sender: TObject);
    begin
    panel1.Caption:=‘锁定远程计算机‘;
    end;

    procedure TForm1.unlockClick(Sender: TObject);
    begin
    panel1.Caption:=‘恢复远程计算机‘;
    end;

    procedure TForm1.kzConnecting(Sender: TObject; Socket: TCustomWinSocket);
    begin
    panel1.Caption:=‘正在连接‘+ipbox.Text;
    end;

    procedure TForm1.kzError(Sender: TObject; Socket: TCustomWinSocket;
    ErrorEvent: TErrorEvent; var ErrorCode: Integer);
    begin
    kz.Active:=false;
    panel1.Caption:=‘网络连接出错,请重试!‘;
    end;

    procedure TForm1.ipboxChange(Sender: TObject);
    begin
    button4.Caption:=‘连接(&C)‘;
    kz.active:=false;
    end;

    procedure TForm1.wmicb(var msg:TMessage);
    var tcwz:TPoint;
    begin
    case msg.LParam of
    wm_lbuttonup:
    display;
    wm_rbuttonup:
    begin
    getcursorpos(tcwz);
    tccd.Popup(tcwz.x,tcwz.y);
    end;
    end;
    end;
    procedure TForm1.N3Click(Sender: TObject);
    begin

    procedure TForm1.kzClientRead(Sender: TObject;
    Socket: TCustomWinSocket);
    var buf:array[0..buffer-1] of char;//开辟一个缓冲区来保存要发送的数据
    sendsize,temp:integer;
    temps:string;
    begin
    temps:=Socket.ReceiveText;
    if temps=‘cut‘ then //如果是截屏指令
    begin
    if bmpstream.Size=0 then screencap(0,0,800,600);//如果没生成图像就截屏
    if leftsize>buffer then sendsize:=buffer
    else sendsize:=leftsize;
    bmpstream.ReadBuffer(buf,sendsize);//从内存流中将数据读入缓冲区
    leftsize:=leftsize-sendsize;
    if leftsize=0 then bmpstream.clear;
    socket.Sendbuf(buf,sendsize);//发送数据
    end
    else if temps=‘ygj‘ then ExitWindowsEx(EWX_SHUTDOWN,0)//关闭机器
    else if temps=‘yqd‘ then ExitWindowsEx(EWX_REBOOT,0)//重新启动机器
    else if temps=‘sdj‘ then//如果是锁定机器指令
    begin
    enablewindow(getdesktopwindow,false);
    end
    else if temps=‘jsj‘ then//如果是解除指令
    begin
    enablewindow(getdesktopwindow,true);
    end
    end;
    end.

    http://blog.sina.com.cn/s/blog_562349090100zufn.html

  • 相关阅读:
    C#调用Halcon
    C#跨窗体程序调用方法的具体操作
    C#调用DLL报错:试图加载格式不正确的程序
    C#窗体程序设置禁用关闭按钮
    C#窗体程序设置禁用关闭按钮
    C#在字符串中查询指定字符串是否存在
    poj1654
    poj1873
    poj2451
    poj1113
  • 原文地址:https://www.cnblogs.com/findumars/p/6435589.html
Copyright © 2020-2023  润新知