C# 多线程 ping

发布于 2024-10-20 09:47:51 字数 1529 浏览 2 评论 0原文

我正在开发一个网络监控应用程序,它对(未知)数量的主机执行 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;
        }
    }
}

I'm working on a network monitoring application, that pings a (not known) number of hosts. So far I have the code below. I've made a class PingHost with a function zping and I called it with the help of a timer once every 2 seconds to let the 2 pings to finish, even if one of them gets TimedOut. But I think a better solution is to generate a new thread for every ping, so that the ping of every host would be independent.

Can anyone give me a hint how to do this?

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;
        }
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

栖迟 2024-10-27 09:47:51

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

If you use .NET 4 you can use Parallel.Invoke.

尤怨 2024-10-27 09:47:51

您可以处理 Ping.PingCompleted 事件:

ping.PingCompleted += new PingCompletedEventHandler(ping_PingCompleted);

然后使用:

ping.SendAsync()

旁注:为您的类和例程选择更合适的名称。 PingHost 更适合作为例程名称

You could handle the Ping.PingCompleted event:

ping.PingCompleted += new PingCompletedEventHandler(ping_PingCompleted);

then use:

ping.SendAsync()

side note: Choose more suitable names for your classes and routines. PingHost is more suitable as a routine name

黑寡妇 2024-10-27 09:47:51

有一次我写了这样一个解决方案(它不断地 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;
    }
}

Once I wrote such a solution (it constantly pings about 300 machines):

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 
quot;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(
quot;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(
quot;error: {p}");
                } catch (Exception ee) {
                    log?.ErrorSource(ee);
                    Debug.WriteLine(
quot;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;
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文