所以我在c#中制作网络扫描程序,将所有连接的设备显示在同一网络中。我这样做的方法是对从192.168.0.1到192.168.0.255的所有IP执行ping命令。
private void IPlook_Tick(object sender, EventArgs e)
{
Properties.Settings.Default.nextIP += 1;
if (Properties.Settings.Default.nextIP >= 255)
{
IPlook.Stop();
}
string IP = "192.168.0." + Properties.Settings.Default.nextIP.ToString();
CurIP.Text = IP;
//See if online
try
{
Ping ping = new Ping();
PingReply pingreply = ping.Send(IP);
if (pingreply.Status == IPStatus.Success)
{
string Hostname = Dns.GetHostByAddress(IP).HostName;
dataGridView1.Rows.Add(Hostname, IP, "");
}
else
{
}
}
catch (Exception er)
{
MessageBox.Show("Something Went Wrong", "Error Alert", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
这个工作正常,但问题是它需要很长时间非常并使程序滞后。我已将计时器的间隔设置为50。
感谢任何帮助。
合法
答案 0 :(得分:0)
你正在一个接一个地运行ping。这意味着您必须等待超时到期255次。同时启动多次ping。使用await
在这里会有很多意义。
此外,取消阻止UI线程,以便在此过程中不冻结UI。有许多技术可以做到这一点。 await
恰好解决了这个问题。
我不明白你为什么要使用计时器。如果没有理由那么简单地删除所有计时器的东西。使用循环。
答案 1 :(得分:0)
如果我正确地读取您的代码,那么您将允许计时器触发255次并且在每次执行中正好ping一台计算机。我不确定你为什么使用Settings类存储当前的迭代次数。
您可以循环1到255并使用Ping.SendAsync
方法异步启动每个Ping请求。不需要计时器。
另请参阅this question以及有关广播ping的答案/评论。
答案 2 :(得分:0)
如何一次性解决所有问题(来自async
方法):
IPAddress start = IPAddress.Parse("192.168.1.1");
var bytes = start.GetAddressBytes();
var leastSigByte= start.GetAddressBytes().Last();
var range= 255 - leastSigByte;
var pingReplyTasks = Enumerable.Range(leastSigByte,range)
.Select(x=>{
var p = new Ping();
var bb = start.GetAddressBytes();
bb[3] = (byte)x;
var destIp = new IPAddress(bb);
var pingResultTask = p.SendPingAsync(destIp);
return new{pingResultTask, addr = destIp};
})
.ToList();
await Task.WhenAll(pingReplyTasks.Select(x=>x.pingResultTask));
foreach(var pr in pingReplyTasks)
{
var tsk = pr.pingResultTask;
var pingResult = tsk.Result; //we know these are completed tasks
var ip = pr.addr;
Console.WriteLine("{0} : {1}",ip,pingResult.Status);
}
您可能不想ping addresses ending in 0 or 255。
答案 3 :(得分:0)
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.NetworkInformation;
using System.Threading.Tasks;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
// Can build your list of IPs using a for loop
List<IPAddress> ips = new List<IPAddress>
{
new IPAddress(new byte[] {192, 168, 0, 1}),
new IPAddress(new byte[] {192, 168, 0, 2}),
// More ips in this list.
};
// Exactly what do you do with initiated tasks will depend on your specific scenario.
List<Task> tps = new List<Task>();
foreach(var ip in ips)
{
tps.Add(InitiatePing(ip));
}
// Needed so that console app doesn't exit..
Console.ReadLine();
}
private static async Task InitiatePing(IPAddress ip)
{
// Note, this API is different from SendAsync API you are using
// You may also want to reuse Ping instance instead of creating new one each time.
var result = await new Ping().SendPingAsync(ip);
// Process your result here, however you want.
Console.WriteLine(result.Address + "-" + result.Status + "-" + result.RoundtripTime);
}
}
}