簡體   English   中英

C#多線程ping

[英]C# multi-thread ping

我正在開發一個網絡監控應用程序,它可以 ping(未知)數量的主機。 到目前為止,我有下面的代碼。 我已經創建了一個帶有函數zping的類PingHost並且我在計時器的幫助下每 2 秒調用一次以讓 2 個 ping 完成,即使其中一個得到TimedOut 但我認為更好的解決方案是為每個 ping 生成一個新線程,這樣每個主機的 ping 都是獨立的。

誰能給我一個提示如何做到這一點?

namespace pinguin
{
    public partial class Form1 : Form
    {
        public Form1()
        {

            InitializeComponent();


        }

        private void timer1_Tick(object sender, EventArgs e)
        {

            PingHost caca = new PingHost();
            PingHost caca1 = new PingHost();
            this.label1.Text = caca.zping("89.115.14.160");
            this.label2.Text = caca1.zping("89.115.14.129");



        }

    }

    public class PingHost
    {


        public string zping(string dest)
        {
            Application.DoEvents();
            Ping sender = new Ping();
            PingOptions options = new PingOptions();
            options.DontFragment = true;

            string data = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
            byte[] buffer = Encoding.ASCII.GetBytes(data);
            int timeout = 50;
            int failed = 0;
            int pingAmount = 5;
            string stat = "";
            PingReply reply = sender.Send(dest, timeout, buffer, options);
            if (reply.Status == IPStatus.Success)
            {
                stat = "ok";
            }
            else
            {
                stat = "not ok!";
            }



            return stat;
        }
    }
}

如果您使用 .NET 4,您可以使用Parallel.Invoke

您可以處理Ping.PingCompleted事件:

ping.PingCompleted += new PingCompletedEventHandler(ping_PingCompleted);

然后使用:

ping.SendAsync()

旁注:為您的課程和例程選擇更合適的名稱。 PingHost 更適合作為例程名稱

一旦我寫了這樣一個解決方案(它不斷 ping 大約 300 台機器):

public class ManyAdressPing {
    private readonly bool bAutoStarted;
    private readonly CancellationTokenSource cancel = new CancellationTokenSource();
    public ConcurrentDictionary<IPAddress, OneAddressPing> pingi = new ConcurrentDictionary<IPAddress, OneAddressPing>();
    public ManyAdressPing(bool AutoStarted = true) {
        bAutoStarted = AutoStarted;
    }
    public int CountPings => pingi.Count;
    public void AddPingAddress(IPAddress addr, int msTimeOut = 3000, int BetweenPing = 3000) {
        var oap = new OneAddressPing(addr, cancel.Token, msTimeOut, BetweenPing);
        if (bAutoStarted) oap.Start();
        pingi.TryAdd(oap.ipAddress, oap);
    }
    public void RemovePingAddress(IPAddress addr) {
        if (pingi.TryRemove(addr, out var p)) p.Stop();
    }
    public void Stop() {
        cancel.Cancel();
        foreach (var pair in pingi) pair.Value.Stop();
    }
    public PingReply GetReply(IPAddress addr) {
        if (pingi.ContainsKey(addr)) return pingi[addr].GetReply();
        return null;
    }
    public Tuple<long, long> GetSuccessOperation(IPAddress addr) {
        if (pingi.ContainsKey(addr)) return pingi[addr].GetSuccessOperation();
        return null;
    }
    public PingReply[] GetReply() {
        PingReply[] ret = pingi.Values.Select(x=>x.GetReply()).ToArray();
        return ret;
    }
    public PingInfo GetPingInfo(IPAddress addr) {
        if (pingi.ContainsKey(addr)) {
            var ret = new PingInfo();
            var p = pingi[addr];
            ret.reply = p.GetReply();
            ret.SuccessPing = p._SuccessReply;
            ret.FailPing = p._FailReply;
            ret.LastSuccessPing = p.LastSuccessfullPing;
            return ret;
        }

        return null;
    }
    public bool IsPinged(IPAddress addr) {
        if (pingi.ContainsKey(addr)) return true;
        return false;
    }
    public IPAddress[] GetAddressesPing() {
        return pingi.Keys.ToArray();
    }
}
public class PingInfo {
    public PingReply reply;
    public long SuccessPing = 0;
    public long FailPing = 0;
    public DateTime LastSuccessPing;
    public override string ToString() {
        return $"Sping: {SuccessPing} last={LastSuccessPing}, Fping:{FailPing}, reply:{reply}";
    }
}
public class OneAddressPing {
    public static byte[] bu = {
        0
    };
    public long _FailReply;
    public long _SuccessReply;
    private bool bStop = false;
    private readonly CancellationToken cancellationToken;
    public DateTime LastSuccessfullPing = DateTime.MinValue;
    public int mSecBetweenPing = 3000;
    public Ping ping;
    public PingOptions popt;
    private Task pTask;
    // Here is a self-written LIFO stack
    public LightQueue<PingReply> replys = new LightQueue<PingReply>(10);
    private readonly AutoResetEvent reset = new AutoResetEvent(false);
    private Logger log = null;
    private Task pinging = null;
    public OneAddressPing(IPAddress addr, CancellationToken ct, int timeOut = 3000, int BetweenPing = 3000, Logger _log =null) {
        ipAddress = addr;
        popt = new PingOptions();
        popt.DontFragment = false;
        cancellationToken = ct;
        mSecTimeOut = timeOut;
        mSecBetweenPing = BetweenPing;
        log = _log;
    }
    public int mSecTimeOut { get; set; } = 3000;
    public IPAddress ipAddress { get; set; }
    public int CountPings => replys.Length;
    private void SetReply(PingReply rep) {
        if (rep == null) return;
        replys.Put(rep);
        if (rep.Status == IPStatus.Success) {
            Interlocked.Increment(ref _SuccessReply);
            LastSuccessfullPing = DateTime.Now;
        } else {
            Interlocked.Increment(ref _FailReply);
        }
    }
    public async Task Start() {
        if (pTask == null || pTask.Status != TaskStatus.Running) {
            ping = new Ping();
            Task.Factory.StartNew(PingCircle, TaskCreationOptions.RunContinuationsAsynchronously | TaskCreationOptions.LongRunning);                 pTask = Task.Run(PingCircle, cancellationToken);
        }
    }
    public void Stop() {
        if (pTask.Status == TaskStatus.Running) {
            bStop = true;
            try {
                pTask.Wait(mSecTimeOut, cancellationToken);
            } catch (Exception ex) {
                log.ErrorSource($"Error ping stop: {ex.Message}");
            } 
        }
    }
    private async Task PingCircle() {
        while (cancellationToken.IsCancellationRequested == false && !bStop) {
            try {
                try {
                    PingReply rep = await ping.SendPingAsync(ipAddress, mSecTimeOut, bu,popt);
                    if (rep != null) SetReply(rep);
                } catch (PingException p) {
                    // ignore ping error
                    Debug.WriteLine($"error: {p}");
                } catch (Exception ee) {
                    log?.ErrorSource(ee);
                    Debug.WriteLine($"error: {ee}");
                }
                await Task.Delay(mSecBetweenPing, cancellationToken);
            } catch (Exception ee) {
                log?.ErrorSource(ee);
            }
        }
    }
    public PingReply GetReply() {
        if (replys.IsEmpty) return null;
        return replys.PeekLast(0);
    }
    public Tuple<long, long> GetSuccessOperation() {
        return new Tuple<long, long>(_SuccessReply, _FailReply);
    }
    public bool LongPingSuccess() {
        int ret = 0;
        for (int i = 0; i < 5; i++) {
            var r = replys.PeekLast(i);
            if (r.Status == IPStatus.Success) ret++;
        }

        if (ret > 2) return true;
        return false;
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM