C# .NET Ping()提供错误的超时?
我有一个脚本,它每秒循环并向主机发送一个ping。其目的是在我的家庭网络上测试无线性能。问题是,我的脚本似乎有超时,而任何一个客户端(pingER和pingEE)上的标准“ping-t”都没有超时。事实上,在过去30分钟内,没有一次超时,而我的脚本每隔几分钟就会收到超时回复 我的基本脚本如下。在所有情况下,当它发生时,我的答复是TimedOut,响应时间为0毫秒。我的脚本是否导致错误超时?谢谢 编辑:更新代码以反映最新的更改,仍然具有相同的行为C# .NET Ping()提供错误的超时?,c#,.net,network-programming,ping,C#,.net,Network Programming,Ping,我有一个脚本,它每秒循环并向主机发送一个ping。其目的是在我的家庭网络上测试无线性能。问题是,我的脚本似乎有超时,而任何一个客户端(pingER和pingEE)上的标准“ping-t”都没有超时。事实上,在过去30分钟内,没有一次超时,而我的脚本每隔几分钟就会收到超时回复 我的基本脚本如下。在所有情况下,当它发生时,我的答复是TimedOut,响应时间为0毫秒。我的脚本是否导致错误超时?谢谢 编辑:更新代码以反映最新的更改,仍然具有相同的行为 while (true) { System
while (true)
{
System.Threading.Thread.Sleep(delay);
var builder = new StringBuilder();
hosts.ForEach(h =>
{
var buffer = new byte[32];
var reply = ping.Send(h, 4000, buffer, new PingOptions(600, true));
var error = reply.Status != IPStatus.Success || reply.RoundtripTime > maxRoundTrip;
if (verbose || error)
{
builder.AppendFormat("{0}: {1} ({2}ms)", h, reply.Status, reply.RoundtripTime);
builder.Append(Environment.NewLine);
if (error)
{
WriteLog(h, reply);
SendEmail(h, reply);
}
}
});
Console.WriteLine(DateTime.Now);
Console.WriteLine(builder.ToString());
}
在我的例子中,字节数组大小是主要原因(我编写了一个类似的ping应用程序) 什么时候 2014/3/30 11:29:26 8.8.8.8:TimedOut(0毫秒) 改为
var buffer = new byte[32];
2014/3/30 11:32:50
8.8.8.8:成功(8ms)
我推断,ping缓冲区如果太高,则ICMP回显消息可能会被分段,变成多个数据包,然后仅发送出去,因此它无法在超时时间内完成ping。(但似乎回答中提到的OP是主机名解决问题,那么可能是我的推断错误)
我的示例代码
using System;
using System.Net;
using System.Net.NetworkInformation;
using System.Text;
namespace ConsoleApplication6
{
class Program
{
static void Main(string[] args)
{
int delay = 1000;
Ping ping = new Ping();
//OP using something else?
System.Net.IPAddress h = IPAddress.Parse("8.8.8.8");
while (true)
{
System.Threading.Thread.Sleep(delay);
var builder = new StringBuilder();
//change buffer size change the result...
//var buffer = new byte[65500];
var buffer = new byte[32];
var reply = ping.Send(h, 1000, buffer, new PingOptions(600, false));
var error = reply.Status != IPStatus.Success || reply.RoundtripTime > 3000;
if (error)
{
builder.AppendFormat("{0}: {1} ({2}ms)", h, reply.Status, reply.RoundtripTime);
builder.Append(Environment.NewLine);
}
else
{
builder.AppendFormat("{0}: {1} ({2}ms)", h, reply.Status, reply.RoundtripTime);
}
Console.WriteLine(DateTime.Now);
Console.WriteLine(builder.ToString());
}
}
}
}
1000是ping回复的超时(ms)…如果您的
ping-t
超时值小于1000或者maxRoundTrip
的值小于1000,那么您将检查两个不同ping中的不同超时情况(.NETping.Send
vs.ping-t
)。默认Windows ping超时为4000毫秒
在.NET代码中,您发送的最大缓冲区大小为65500字节。默认的Windows ping命令只发送32字节的数据
因此,超时或缓冲区大小之间的差异很可能是导致差异的原因
有关.NET Ping.Send方法的更多信息:我可能已经找到了。我使用的是有关机器的netbios名称。我猜每次ping时,它都会在往返过程中考虑IP查找,并超时。当我只使用IP时,它工作正常,没有超时
谢谢你的意见 我看到了与OP相同的行为。My ping.Send()只发送字节[30]的缓冲区,并且始终使用显式IP,因此不涉及DNS/NetBIOS。我尝试过改变超时值,但在使用命令行ping时,始终可以看到Send()的常规超时返回与零超时
public PingCheck(string address, int timeout = 250, int pingNbr = 1)
{
var rtn = IPAddress.TryParse(address, out IPAddress addr);
if (rtn)
{
IpAddress = addr;
var dataSend = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
var pinger = new Ping();
var pingerOptions = new PingOptions();
pingerOptions.DontFragment = true;
var buffer = Encoding.ASCII.GetBytes(dataSend);
var statusList = new List<IPStatus>();
var lossList = new List<bool>();
var tripList = new List<long>();
for (int i=0; i<pingNbr; i++)
{
var pingerReply = pinger.Send(addr, timeout, buffer, pingerOptions);
var bufback = pingerReply.Buffer;
var dataBack = Encoding.ASCII.GetString(bufback);
var status = pingerReply.Status;
var loss = (dataSend != dataBack);
var msecs = pingerReply.RoundtripTime;
statusList.Add(status);
lossList.Add(loss);
tripList.Add(msecs);
}
// TODO: Add statistics check
}
else
throw new PingException("No IP Address");
}
public PingCheck(字符串地址,int timeout=250,int pingNbr=1)
{
var rtn=IPAddress.TryParse(地址,out-IPAddress-addr);
如果(rtn)
{
IpAddress=addr;
var dataSend=“aaaaaaaaaaaaaaaaaaaaaaaa”;
var pinger=new Ping();
var pingerOptions=新的PingOptions();
pingerOptions.DontFragment=true;
var buffer=Encoding.ASCII.GetBytes(dataSend);
var statusList=新列表();
var lossList=新列表();
var tripList=新列表();
对于(int i=0;i错误条件失败?1000毫秒的回复时间应该足够长,但是否有特殊原因导致您不使用标准ping?我之所以使用它,是因为我想让它运行,并在出现错误时提醒我和记录。但是,在我的情况下,它似乎不太可靠,或者我做错了什么。运行CMD ping.exe on同样的机器不会让我超时。“延迟”设置为1000ms。发送调用的超时时间我已经更改,并且得到了相同的结果。感谢您的回复。我将缓冲区减少到32字节,并将超时时间增加到4000ms,但仍然以相同的频率出现超时。您正在比较的ping-t
命令使用哪些选项?以及应用程序的类型是什么您是否在(网站/IIS、命令行工具、WinForms)中运行.NETPing.Send
?如果是IIS,则可以检查应用程序池回收时间。您使用的是.NET的哪个版本?您是否同时增加了Ping.Send
超时和maxRoundTrip
超时值?CMD Ping只是“Ping-t”。该应用程序是在我的桌面计算机上运行的c#4.5控制台应用程序。我在其他计算机上运行它时得到相同的结果。Ping状态为TimedOut。我尝试了你的建议,但仍然得到了随机超时。此外,我已经有一个标准的CMD Ping在同一时间运行了一个多小时,没有一个超时。我可以知道你如何使用define吗netbios名称在C#中?或者你能告诉我你如何在你的程序中定义h
吗?谢谢你听我说明白了!是的,这是有道理的,因为ping-t
在第一次ping之前只做了一次nslookup,但是.NET代码在每次迭代中都会做查找(除非有某种DNS缓存在幕后进行)。@V-SHY所说的“netbios”名称,他只是指他使用的是FQDN而不是IP地址;h
被定义为ForEach
lamda表达式中的第一个变量。
var reply = ping.Send(h, 1000, buffer, new PingOptions(600, false));
public PingCheck(string address, int timeout = 250, int pingNbr = 1)
{
var rtn = IPAddress.TryParse(address, out IPAddress addr);
if (rtn)
{
IpAddress = addr;
var dataSend = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
var pinger = new Ping();
var pingerOptions = new PingOptions();
pingerOptions.DontFragment = true;
var buffer = Encoding.ASCII.GetBytes(dataSend);
var statusList = new List<IPStatus>();
var lossList = new List<bool>();
var tripList = new List<long>();
for (int i=0; i<pingNbr; i++)
{
var pingerReply = pinger.Send(addr, timeout, buffer, pingerOptions);
var bufback = pingerReply.Buffer;
var dataBack = Encoding.ASCII.GetString(bufback);
var status = pingerReply.Status;
var loss = (dataSend != dataBack);
var msecs = pingerReply.RoundtripTime;
statusList.Add(status);
lossList.Add(loss);
tripList.Add(msecs);
}
// TODO: Add statistics check
}
else
throw new PingException("No IP Address");
}