在Mono3.2.8下运行的Ping.Send在C# .Net 4.5中遇到了延迟问题。我的代码如下所示:
using(var sw = new StreamWriter("/ping.txt"))
{
var ping = new Ping();
PingReply reply;
sw.WriteLine("Pre ping: {0}", DateTime.Now);
// Ping local machine
reply = ping.Send("172.16.1.100", 60);
sw.WriteLine("Post ping: {0}", DateTime.Now);
if (reply != null && reply.Status == IPStatus.Success)
{
sw.WriteLine("Success! RTT: {0}", reply.RoundtripTime);
}
sw.WriteLine("Pre ping: {0}", DateTime.Now);
// Ping Google
reply = ping.Send("216.58.220.110", 60);
sw.WriteLine("Post ping: {0}", DateTime.Now);
if (reply != null && reply.Status == IPStatus.Success)
{
sw.WriteLine("Success! RTT: {0}", reply.RoundtripTime);
}
}在Linux上在Mono下运行上述代码的输出是:
您可以看到,在"Pre“和"Post”时间戳之间,延迟了20秒(这是一致的,总是20秒)。运行Mono的机器在相同的172.16.1.*网络上,我把Google放在那里进行额外的测试。
在我的Windows机器上本地运行相同的代码会产生以下输出(pings不会延迟):
对这里发生了什么有什么想法吗?我需要敲击数百台机器,所以延迟20秒是不能接受的。
更新:我尝试在下面的代码中使用Ping.SendAsync方法:
private void PingAsyncTest()
{
var ipAddresses = new List<String> { "172.16.1.100", "216.58.220.110" };
foreach (var ipAddress in ipAddresses)
{
using (var ping = new Ping())
{
ping.PingCompleted += PingCompleted;
ping.SendAsync(IPAddress.Parse(ipAddress), 1000);
}
}
}
private void PingCompleted(object sender, PingCompletedEventArgs e)
{
if (e.Reply.Status == IPStatus.Success)
{
// Update successful ping in the DB.
}
}我仍然看到从SendAsync呼叫到回复进入PingCompleted之间的20秒延迟。这比原来的代码稍微好一些,在原始代码中,应用程序在发送下一个ping之前等待20秒。这样,所有的ping都是异步发送和接收的,因此每个ping不需要等待20秒。不过还是不太理想。
发布于 2015-03-17 08:43:38
这种方式在很大程度上取决于权限的设置方式。
如果应用程序获得足够的权限,它将直接尝试发送ICMP请求。另一方面,如果不允许发送ICMP,它将运行ping可执行文件(试图在/bin/ping、/sbin/ping和/usr/sbin/ping中找到它)。
首先,您可能需要检查哪些是实际发生的。当您尝试执行pings时,ping会执行吗?如果你sudo你的应用程序,它会有帮助吗?
默认的超时时间是4秒,所以它不应该花费20秒--在此之前您应该有一个超时时间。并且您显式地传递了60毫秒的超时。
所有这些(以及对Mono中的代码处理pings的仔细查看)都表明了以下几点:
Ping类本身的初始设置需要20,000--查询功能、查找ping等。显然不是这样,因为您正在尝试两个ping,每个都要花很长时间。Dns.GetHostName或Dns.GetHostAddresses。分别检查这两个选项和ping本身。最后一点也暗示了另一个问题--如果你想要平很多不同的主机,你真的不想使用Ping,至少在Linux上不想使用。相反,您需要确保应用程序运行特权(足够的权限来执行原始ICMP),并通过一个Socket处理所有ICMP请求和答复。如果您使用Ping.Send并行发送100个请求,那么每个Ping.Send都必须通过所有的回复,而不仅仅是他们所期望的回复。此外,使用60 as作为超时听起来不是个好主意,因为代码使用DateTime.Now来检查超时,这可能具有非常低的超时分辨率。
与发送请求和等待回复不同,您实际上希望始终使用异步套接字来发送和接收,直到您遍历所有要ping的主机,同时检查没有及时收到答复的主机。
https://stackoverflow.com/questions/29094041
复制相似问题