2

ローカルネットワークをスキャンして接続されたPCを探すアプリケーションがあります。

ここに画像の説明を入力してください

クライアント情報(IPアドレス、MACアドレス、ホスト名...)と接続状態(ダウンロードレート、アップロードレート)を取得して、に入れたいのですListViewが、この情報が一定ではないのが問題です!

この情報をリアルタイムで取得するにはどうすればよいですか?クライアントの情報がListView変わるたびに、の情報は変わりますか?

私の現在のコード:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Collections;
using System.Text;
using System.Windows.Forms;
using NetUtils;
using System.Net;


namespace WindowsFormsApplication5
{


public partial class Form1 : Form
{
    private IPScanner _scanner;

    private class HostSorterByIP : IComparer
    {
        public int Compare(object x, object y)
        {
            byte[] bytes1 = ((IPScanHostState)((ListViewItem)x).Tag).Address.GetAddressBytes();
            byte[] bytes2 = ((IPScanHostState)((ListViewItem)y).Tag).Address.GetAddressBytes();

            int i = bytes1.Length - 1;
            for (; i > 0 && bytes1[i] == bytes2[i]; i--)
                ;

            return bytes1[i] - bytes2[i];
        }
    }

    public Form1()
    {
        InitializeComponent();

        _scanner = new IPScanner((int)_spnConcurrentPings.Value, (int)_spnPingsPerScan.Value, _cbContinuousScan.Checked,
            (int)_spnTimeout.Value, (int)_spnTTL.Value, _cbDontFragment.Checked, (int)_spnBufferSize.Value);

        _scanner.OnAliveHostFound += new IPScanner.AliveHostFoundDelegate(_scanner_OnAliveHostFound);

        _scanner.OnStartScan += new IPScanner.ScanStateChangeDelegate(_scanner_OnStartScan);
        _scanner.OnStopScan += new IPScanner.ScanStateChangeDelegate(_scanner_OnStopScan);
        _scanner.OnRestartScan +=new IPScanner.ScanStateChangeDelegate(_scanner_OnRestartScan);
        _scanner.OnScanProgressUpdate +=new IPScanner.ScanProgressUpdateDelegate(_scanner_OnScanProgressUpdate);

        _lvAliveHosts.ListViewItemSorter = new HostSorterByIP();

        _cmbRangeType.SelectedIndex = 0;
    }

    private void _scanner_OnAliveHostFound(IPScanner scanner, IPScanHostState host)
    {
        if (InvokeRequired)
        {
            BeginInvoke(new IPScanner.AliveHostFoundDelegate(_scanner_OnAliveHostFound), scanner, host);
            return;
        }

        ListViewItem item = new ListViewItem();
        item.Tag = host;

        item.BackColor = Color.GreenYellow;
        item.SubItems.Add(host.Address.ToString());
        item.SubItems.Add("");
        item.SubItems.Add("");
        item.SubItems.Add("");

        _lvAliveHosts.Items.Add(item);
        _lvAliveHosts.Sort();

        host.OnHostNameAvailable += new IPScanHostState.HostNameAvailableDelegate(host_OnHostNameAvailable);
        host.OnStateChange += new IPScanHostState.StateChangeDelegate(host_OnStateChange);

        if (!host.IsTesting())
        {
            item.ImageIndex = (int)host.QualityCategory;
            item.SubItems[2].Text = host.AvgResponseTime.ToString("F02") + " ms";
            item.SubItems[3].Text = ((float)(host.LossCount) / host.PingsCount).ToString("P");
            item.SubItems[4].Text = host.HostName;
        }

        //AddLogEntry("Host [" + host.Address.ToString() + "] is alive.");

        Timer newTimer = new Timer();
        newTimer.Tag = item;
        newTimer.Interval = 2000;
        newTimer.Tick += new EventHandler(newTimer_Tick);

        newTimer.Enabled = true;
    }

    void host_OnHostNameAvailable(IPScanHostState host)
    {
        if (InvokeRequired)
        {
            BeginInvoke(new IPScanHostState.HostNameAvailableDelegate(host_OnHostNameAvailable), host);
            return;
        }

        ListViewItem item = FindListViewItem(host);
        if (item != null)
            item.SubItems[4].Text = host.HostName;
    }

    private ListViewItem FindListViewItem(IPScanHostState host)
    {
        foreach (ListViewItem item in _lvAliveHosts.Items)
        {
            if (item.Tag == host)
                return item;
        }

        return null;
    }

    private void host_OnStateChange(IPScanHostState host, IPScanHostState.State oldState)
    {
        if (InvokeRequired)
        {
            BeginInvoke(new IPScanHostState.StateChangeDelegate(host_OnStateChange), host, oldState);
            return;
        }

        if (!host.IsTesting())
        {
            ListViewItem item = FindListViewItem(host);
            if (item != null)
            {
                if (host.IsAlive())
                {
                    item.ImageIndex = (int)host.QualityCategory;
                    item.SubItems[2].Text = host.AvgResponseTime.ToString("F02") + " ms";
                    item.SubItems[3].Text = ((float)(host.LossCount) / host.PingsCount).ToString("P");
                }
                else
                {
                    //AddLogEntry("Host [" + host.Address.ToString() + "] died.");

                    host.OnStateChange -= host_OnStateChange;
                    host.OnHostNameAvailable -= host_OnHostNameAvailable;

                    item.BackColor = Color.IndianRed;

                    Timer removeTimer = new Timer();
                    removeTimer.Tag = item;
                    removeTimer.Interval = 2000;
                    removeTimer.Tick += new EventHandler(removeTimer_Tick);

                    removeTimer.Enabled = true;
                }
            }
        }
    }

    void newTimer_Tick(object sender, EventArgs e)
    {
        Timer timer = (Timer)sender;

        timer.Stop();
        timer.Tick -= newTimer_Tick;

        ListViewItem item = (ListViewItem)timer.Tag;
        item.BackColor = Color.White;
    }

    void removeTimer_Tick(object sender, EventArgs e)
    {
        Timer timer = (Timer)sender;

        timer.Stop();
        timer.Tick -= newTimer_Tick;

        ListViewItem item = (ListViewItem)timer.Tag;
        _lvAliveHosts.Items.Remove(item);
    }

    private void _scanner_OnStartScan(IPScanner scanner)
    {
        if (InvokeRequired)
        {
            BeginInvoke(new IPScanner.ScanStateChangeDelegate(_scanner_OnStartScan), scanner);
            return;
        }

        foreach (ListViewItem item in _lvAliveHosts.Items)
        {
            ((IPScanHostState)item.Tag).OnStateChange -= host_OnStateChange;
            ((IPScanHostState)item.Tag).OnHostNameAvailable -= host_OnHostNameAvailable;
        }

        _lvAliveHosts.Items.Clear();

        _prgScanProgress.Value = 0;

        EnableSettings(false);
    }

    private void EnableSettings(bool enable)
    {
        _cmbRangeType.Enabled = _tbRangeStart.Enabled = _tbRangeEnd.Enabled = _spnTimeout.Enabled = _spnTTL.Enabled = _spnBufferSize.Enabled = _cbDontFragment.Enabled =
            _spnConcurrentPings.Enabled = _spnPingsPerScan.Enabled = _cbContinuousScan.Enabled = enable;

        _btnStartStop.Text = enable ? "&Start" : "&Stop";
        if (enable)
            _prgScanProgress.Text = "Scanner is not running!";
    }

    private void _btnStartStop_Click(object sender, EventArgs e)
    {
        if (!_scanner.Active)
        {
            try
            {
                _scanner.Start(_cmbRangeType.SelectedIndex == 0
                    ? new IPScanRange(IPAddress.Parse(_tbRangeStart.Text), IPAddress.Parse(_tbRangeEnd.Text))
                    : new IPScanRange(IPAddress.Parse(_tbRangeStart.Text), int.Parse(_tbRangeEnd.Text)));
            }
            catch (FormatException)
            {
                MessageBox.Show(this, "Cannot parse IP range or subnetmask!", "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        else
            _scanner.Stop(false);
    }

    private void _scanner_OnStopScan(IPScanner scanner)
    {
        if (InvokeRequired)
        {
            BeginInvoke(new IPScanner.ScanStateChangeDelegate(_scanner_OnStopScan), scanner);
            return;
        }

        EnableSettings(true);


        _prgScanProgress.Value = 0;
    }

    void _scanner_OnRestartScan(IPScanner scanner)
    {
        if (InvokeRequired)
        {
            BeginInvoke(new IPScanner.ScanStateChangeDelegate(_scanner_OnRestartScan), scanner);
            return;
        }


        _prgScanProgress.Value = 0;
    }

    void _scanner_OnScanProgressUpdate(IPScanner scanner, IPAddress currentAddress, ulong progress, ulong total)
    {
        if (InvokeRequired)
        {
            BeginInvoke(new IPScanner.ScanProgressUpdateDelegate(_scanner_OnScanProgressUpdate), scanner, currentAddress, progress, total);
            return;
        }

        int prog = (int)((100 * progress) / total);
        _prgScanProgress.Value = prog;
        _prgScanProgress.Text = prog.ToString() + "%" + " [" + currentAddress.ToString() + "]";
    }

    private void _cmbRangeType_SelectedIndexChanged(object sender, EventArgs e)
    {
        if (_cmbRangeType.SelectedIndex == 0)
        {
            _lRangeSep.Text = "-";
            _lRangeEnd.Text = "Range &End:";
            _tbRangeEnd.Size = new Size(130, _tbRangeEnd.Size.Height);
        }
        else
        {
            _lRangeSep.Text = "/";
            _lRangeEnd.Text = "Subnet &Mask:";
            _tbRangeEnd.Size = new Size(32, _tbRangeEnd.Size.Height);
        }
    }

    //private void _lvAliveHosts_DoubleClick(object sender, EventArgs e) { _btnAddHost_Click(sender, e); }

    private void IPScanForm_FormClosing(object sender, FormClosingEventArgs e) { _scanner.Stop(true); }

    private ListViewItem.ListViewSubItem _activeTooltipSubitem = null;

    private static string[] QualityCategoryNames = { "Very Poor", "Poor", "Fair", "Good", "Very Good", "Excellent", "Perfect" };

    private void _lvAliveHosts_MouseMove(object sender, MouseEventArgs e)
    {
        ListViewItem item = _lvAliveHosts.HitTest(e.Location).Item;
        if (item != null)
        {
            ListViewItem.ListViewSubItem subitem = _lvAliveHosts.HitTest(e.Location).SubItem;
            if (subitem != null && item.SubItems.IndexOf(subitem) == 0)
            {
                if (_activeTooltipSubitem != subitem)
                {
                    _ttQuality.Show("Quality: " + QualityCategoryNames[item.ImageIndex], _lvAliveHosts, item.SubItems[1].Bounds.X, subitem.Bounds.Y);
                    _activeTooltipSubitem = subitem;
                }

                return;
            }
        }

        _activeTooltipSubitem = null;
        _ttQuality.Hide(_lvAliveHosts);
    }


}
}
4

1 に答える 1

2

クライアントのリストを作成し、リストビューに表示します。

バックグラウンドスレッドでは、X秒ごとに、現在のすべてのクライアントをポーリングします。次に、更新されたクライアントのリストを前回の更新からのクライアントのリストと比較します。

あとは、リストに新しいクライアントを追加し、存在しなくなったクライアントを削除する必要があります。

コンテキストに注意し、InvokeRequired()を使用して、バックグラウンドスレッドからUIコントロールにアクセスします。

編集:

バックグラウンドスレッドを実行する方法は次のとおりです。

static void Main(string[] args)
        {

            Thread worker = new Thread(DoBackgroundWork);
        }

        public static void DoBackgroundWork()
        {


            while (true)
            {
                //Sleep 10 seconds
                Thread.Sleep(10000);

                //Do some work and than post to the control using Invoke()

            }

        }
于 2013-03-24T12:06:34.040 に答える