C# Ping.SendAsync陷入无限循环
我正在尝试获取本地网络上所有主机的列表。下列的但是Ping.SendAsync()被困在无限循环中,即使我保持一个非常小的超时,例如20。这是我的密码C# Ping.SendAsync陷入无限循环,c#,networking,ping,C#,Networking,Ping,我正在尝试获取本地网络上所有主机的列表。下列的但是Ping.SendAsync()被困在无限循环中,即使我保持一个非常小的超时,例如20。这是我的密码 static CountdownEvent countdown; static int upCount = 0; static object lockObj = new object(); const bool resolveNames = false; static
static CountdownEvent countdown;
static int upCount = 0;
static object lockObj = new object();
const bool resolveNames = false;
static List<string> activeInterfaces = new List<string>();
static void p_PingCompleted(object sender, PingCompletedEventArgs e)
{
try
{
string ip = (string)e.UserState;
if (e.Reply != null && e.Reply.Status == IPStatus.Success)
{
//if (resolveNames)
//{
// string name;
// try
// {
// IPHostEntry hostEntry = Dns.GetHostEntry(ip);
// name = hostEntry.HostName;
// }
// catch (SocketException ex)
// {
// name = "?";
// }
// Console.WriteLine("{0} ({1}) is up: ({2} ms)", ip, name, e.Reply.RoundtripTime);
//}
//else
//{
activeInterfaces.Add(ip);
Console.WriteLine("{0} is up: ({1} ms)", ip, e.Reply.RoundtripTime);
//}
lock (lockObj)
{
upCount++;
}
}
else if (e.Reply == null)
{
Console.WriteLine("Pinging {0} failed. (Null Reply object?)", ip);
}
countdown.Signal();
}
catch (Exception exp)
{
Console.WriteLine("Here you go...");
}
}
[HttpGet]
[Route("api/pc/getOnlinePCs")]
public List<string> GetOnlinePCs()
{
activeInterfaces.Clear();
//List<string> activeInterfaces=new List<string>();
string ipBase = "";
var host = Dns.GetHostEntry(Dns.GetHostName());
foreach (var ip in host.AddressList)
{
if (ip.AddressFamily == AddressFamily.InterNetwork)
{
ipBase = ip.ToString().Substring(0, (ip.ToString().LastIndexOf(".") + 1));//"10.22.4.";
}
}
countdown = new CountdownEvent(1);
Stopwatch sw = new Stopwatch();
sw.Start();
for (int i = 2; i < 254; i++)
{
string ip = ipBase + i.ToString();
//var tcpClient = new TcpClient();
//tcpClient.Connected += new PingCompletedEventHandler(p_PingCompleted);
Ping ping = new Ping();
ping.PingCompleted += new PingCompletedEventHandler(p_PingCompleted);
countdown.AddCount();
ping.SendAsync(ip, 20, ip);
}
countdown.Signal();
countdown.Wait();
sw.Stop();
TimeSpan span = new TimeSpan(sw.ElapsedTicks);
Console.WriteLine("Took {0} milliseconds. {1} hosts active.", sw.ElapsedMilliseconds, upCount);
Console.ReadLine();
return activeInterfaces;
}
但当我调试代码时,它总是最终阻塞。不例外块和253 pings迭代完成后,再次无限循环@Evk和@jdweng请帮忙
@Evk这是它如何被卡住的图像
Ping SendAsync没有达到预期效果,您可以释放资源,但是您需要自己处理从另一个线程返回的答案,您需要挂接Ping Completed来处理答案 最好是通过在方法中调用ping和来创建方法的异步方法,并通过自己实现来在异步方法中调用方法
Ping SendAsync没有达到预期效果,您可以释放资源,但是您需要自己处理从另一个线程返回的答案,您需要挂接Ping Completed来处理答案 最好是通过在方法中调用ping和来创建方法的异步方法,并通过自己实现来在异步方法中调用方法
它不是在回答你的问题,而是在回答你的任务。我想,你是在使用IP请求来强制查看IP地址,最好使用地址解析协议(也称为ARP) 首先,创建存储数据的结构:
public struct MacIpPair : IEquatable<MacIpPair>
{
/// <summary>
/// Initializes a new instance of the <see cref="MacIpPair"/> struct.
/// </summary>
/// <param name="mac">The mac.</param>
/// <param name="ip">The ip.</param>
/// <param name="type">ARP record status</param>
/// <exception cref="System.ArgumentException">Mac address needs to be provided - mac</exception>
/// <exception cref="System.ArgumentException">IP address needs to be provided - ip</exception>
public MacIpPair(string mac, string ip, ArpStatus type)
{
if (string.IsNullOrEmpty(mac))
{
throw new System.ArgumentException("Mac address needs to be provided", nameof(mac));
}
if (string.IsNullOrEmpty(ip))
{
throw new System.ArgumentException("IP address needs to be provided", nameof(ip));
}
MacAddress = mac;
IpAddress = ip;
Status = type;
}
/// <summary>
/// The mac address
/// </summary>
/// <value>The mac address.</value>
[NotNull]
public string MacAddress { get; }
/// <summary>
/// The ip address
/// </summary>
/// <value>The ip address.</value>
[NotNull]
public string IpAddress { get; }
/// <summary>
/// The status of the ARP entry
/// </summary>
ArpStatus Status { get; }
/// <summary>
/// Determines whether the specified <see cref="System.Object" /> is equal to this instance.
/// </summary>
/// <param name="obj">The object to compare with the current instance.</param>
/// <returns><c>true</c> if the specified <see cref="System.Object" /> is equal to this instance; otherwise, <c>false</c>.</returns>
public override bool Equals(object? obj)
{
return obj is MacIpPair pair && Equals(pair);
}
/// <summary>
/// Indicates whether the current object is equal to another object of the same type.
/// </summary>
/// <param name="other">An object to compare with this object.</param>
/// <returns><see langword="true" /> if the current object is equal to the <paramref name="other" /> parameter; otherwise, <see langword="false" />.</returns>
public bool Equals(MacIpPair other)
{
return MacAddress == other.MacAddress &&
IpAddress == other.IpAddress &&
Status==other.Status
;
}
/// <summary>
/// Returns a hash code for this instance.
/// </summary>
/// <returns>A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table.</returns>
public override int GetHashCode()
{
return HashCode.Combine(MacAddress, IpAddress, Status);
}
/// <summary>
/// Implements the == operator.
/// </summary>
/// <param name="left">The left.</param>
/// <param name="right">The right.</param>
/// <returns>The result of the operator.</returns>
public static bool operator ==(MacIpPair left, MacIpPair right)
{
return left.Equals(right);
}
/// <summary>
/// Implements the != operator.
/// </summary>
/// <param name="left">The left.</param>
/// <param name="right">The right.</param>
/// <returns>The result of the operator.</returns>
public static bool operator !=(MacIpPair left, MacIpPair right)
{
return !(left == right);
}
}
它不是在回答你的问题,而是在回答你的任务。我想,你是在使用IP请求来强制查看IP地址,最好使用地址解析协议(也称为ARP) 首先,创建存储数据的结构:
public struct MacIpPair : IEquatable<MacIpPair>
{
/// <summary>
/// Initializes a new instance of the <see cref="MacIpPair"/> struct.
/// </summary>
/// <param name="mac">The mac.</param>
/// <param name="ip">The ip.</param>
/// <param name="type">ARP record status</param>
/// <exception cref="System.ArgumentException">Mac address needs to be provided - mac</exception>
/// <exception cref="System.ArgumentException">IP address needs to be provided - ip</exception>
public MacIpPair(string mac, string ip, ArpStatus type)
{
if (string.IsNullOrEmpty(mac))
{
throw new System.ArgumentException("Mac address needs to be provided", nameof(mac));
}
if (string.IsNullOrEmpty(ip))
{
throw new System.ArgumentException("IP address needs to be provided", nameof(ip));
}
MacAddress = mac;
IpAddress = ip;
Status = type;
}
/// <summary>
/// The mac address
/// </summary>
/// <value>The mac address.</value>
[NotNull]
public string MacAddress { get; }
/// <summary>
/// The ip address
/// </summary>
/// <value>The ip address.</value>
[NotNull]
public string IpAddress { get; }
/// <summary>
/// The status of the ARP entry
/// </summary>
ArpStatus Status { get; }
/// <summary>
/// Determines whether the specified <see cref="System.Object" /> is equal to this instance.
/// </summary>
/// <param name="obj">The object to compare with the current instance.</param>
/// <returns><c>true</c> if the specified <see cref="System.Object" /> is equal to this instance; otherwise, <c>false</c>.</returns>
public override bool Equals(object? obj)
{
return obj is MacIpPair pair && Equals(pair);
}
/// <summary>
/// Indicates whether the current object is equal to another object of the same type.
/// </summary>
/// <param name="other">An object to compare with this object.</param>
/// <returns><see langword="true" /> if the current object is equal to the <paramref name="other" /> parameter; otherwise, <see langword="false" />.</returns>
public bool Equals(MacIpPair other)
{
return MacAddress == other.MacAddress &&
IpAddress == other.IpAddress &&
Status==other.Status
;
}
/// <summary>
/// Returns a hash code for this instance.
/// </summary>
/// <returns>A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table.</returns>
public override int GetHashCode()
{
return HashCode.Combine(MacAddress, IpAddress, Status);
}
/// <summary>
/// Implements the == operator.
/// </summary>
/// <param name="left">The left.</param>
/// <param name="right">The right.</param>
/// <returns>The result of the operator.</returns>
public static bool operator ==(MacIpPair left, MacIpPair right)
{
return left.Equals(right);
}
/// <summary>
/// Implements the != operator.
/// </summary>
/// <param name="left">The left.</param>
/// <param name="right">The right.</param>
/// <returns>The result of the operator.</returns>
public static bool operator !=(MacIpPair left, MacIpPair right)
{
return !(left == right);
}
}
“但是Ping.SendAsync()卡在无限循环中”-这是怎么回事?您发送了多少Ping?你的循环看起来像是在发送253。如果服务器脱机或找不到,ping将不会完成并超时。如果ping得到响应或超时,回调方法将获得253次调用。问题是倒计时。信号();在代码中处于错误位置。当你得到一个例外,你不是倒计时。在最后一个街区的例外情况下移动到。看起来您遇到了异常。好的,谢谢@jdweng!您能添加一个简单的答案吗?@Evk被困在无限循环中,我的意思是调试器正在运行,但不会再遇到断点。。。我知道,这不是真正的无限loop@jdweng请看一下我的编辑“但是Ping.SendAsync()卡在无限循环中”-这是怎么回事?您发送了多少Ping?你的循环看起来像是在发送253。如果服务器脱机或找不到,ping将不会完成并超时。如果ping得到响应或超时,回调方法将获得253次调用。问题是倒计时。信号();在代码中处于错误位置。当你得到一个例外,你不是倒计时。在最后一个街区的例外情况下移动到。看起来您遇到了异常。好的,谢谢@jdweng!您能添加一个简单的答案吗?@Evk被困在无限循环中,我的意思是调试器正在运行,但不会再遇到断点。。。我知道,这不是真正的无限loop@jdweng请看我的编辑
public struct MacIpPair : IEquatable<MacIpPair>
{
/// <summary>
/// Initializes a new instance of the <see cref="MacIpPair"/> struct.
/// </summary>
/// <param name="mac">The mac.</param>
/// <param name="ip">The ip.</param>
/// <param name="type">ARP record status</param>
/// <exception cref="System.ArgumentException">Mac address needs to be provided - mac</exception>
/// <exception cref="System.ArgumentException">IP address needs to be provided - ip</exception>
public MacIpPair(string mac, string ip, ArpStatus type)
{
if (string.IsNullOrEmpty(mac))
{
throw new System.ArgumentException("Mac address needs to be provided", nameof(mac));
}
if (string.IsNullOrEmpty(ip))
{
throw new System.ArgumentException("IP address needs to be provided", nameof(ip));
}
MacAddress = mac;
IpAddress = ip;
Status = type;
}
/// <summary>
/// The mac address
/// </summary>
/// <value>The mac address.</value>
[NotNull]
public string MacAddress { get; }
/// <summary>
/// The ip address
/// </summary>
/// <value>The ip address.</value>
[NotNull]
public string IpAddress { get; }
/// <summary>
/// The status of the ARP entry
/// </summary>
ArpStatus Status { get; }
/// <summary>
/// Determines whether the specified <see cref="System.Object" /> is equal to this instance.
/// </summary>
/// <param name="obj">The object to compare with the current instance.</param>
/// <returns><c>true</c> if the specified <see cref="System.Object" /> is equal to this instance; otherwise, <c>false</c>.</returns>
public override bool Equals(object? obj)
{
return obj is MacIpPair pair && Equals(pair);
}
/// <summary>
/// Indicates whether the current object is equal to another object of the same type.
/// </summary>
/// <param name="other">An object to compare with this object.</param>
/// <returns><see langword="true" /> if the current object is equal to the <paramref name="other" /> parameter; otherwise, <see langword="false" />.</returns>
public bool Equals(MacIpPair other)
{
return MacAddress == other.MacAddress &&
IpAddress == other.IpAddress &&
Status==other.Status
;
}
/// <summary>
/// Returns a hash code for this instance.
/// </summary>
/// <returns>A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table.</returns>
public override int GetHashCode()
{
return HashCode.Combine(MacAddress, IpAddress, Status);
}
/// <summary>
/// Implements the == operator.
/// </summary>
/// <param name="left">The left.</param>
/// <param name="right">The right.</param>
/// <returns>The result of the operator.</returns>
public static bool operator ==(MacIpPair left, MacIpPair right)
{
return left.Equals(right);
}
/// <summary>
/// Implements the != operator.
/// </summary>
/// <param name="left">The left.</param>
/// <param name="right">The right.</param>
/// <returns>The result of the operator.</returns>
public static bool operator !=(MacIpPair left, MacIpPair right)
{
return !(left == right);
}
}
/// <summary>
/// Gets all mac addresses and IP PAIRS visible to the computer.
/// </summary>
/// <remarks>
/// This will use RRP broadcast to obtain the mac addresses for all devices connected with the DHCP server
/// </remarks>
/// <returns>List<MacIpPair>.</returns>
public static List<MacIpPair> GetAllMacAddressesAndIpPairs()
{
try
{
List<MacIpPair> mip = new List<MacIpPair>();
using System.Diagnostics.Process pProcess = new System.Diagnostics.Process();
pProcess.StartInfo.FileName = "arp";
pProcess.StartInfo.Arguments = "-a ";
pProcess.StartInfo.UseShellExecute = false;
pProcess.StartInfo.RedirectStandardOutput = true;
pProcess.StartInfo.CreateNoWindow = true;
pProcess.Start();
pProcess.WaitForExit();
string cmdOutput = pProcess.StandardOutput.ReadToEnd();
string pattern = @"(?<ip>([0-9]{1,3}\.?){4})\s*(?<mac>([a-f0-9]{2}-?){6})";
foreach (Match? m in Regex.Matches(cmdOutput, pattern, RegexOptions.IgnoreCase))
{
if (m is null)
continue;
mip.Add(new MacIpPair(m.Groups["mac"].Value, m.Groups["ip"].Value, ArpStatus.Static));
}
return mip;
}
catch (Exception e)
{
Walter.TicketService.PostException(e);
throw;
}
}
[DllImport("IpHlpApi.dll", EntryPoint = "GetIpNetTable")]
[return: MarshalAs(UnmanagedType.U4)]
internal static extern int GetIpNetTable(IntPtr pIpNetTable, [MarshalAs(UnmanagedType.U4)] ref int pdwSize, bool bOrder);