我有一个循环的脚本,每秒向主机发送一次ping。其目的是测试家庭网络上的无线性能。问题是,我似乎从我的脚本中获得超时,而在任一客户端(pingER和pingEE)上的标准“ping -t”都没有这样的超时。事实上,在最后30分钟内没有一次超时,而我的脚本每隔几分钟就收到超时回复。
我的基本脚本如下。在所有情况下,当它确实发生时,我的回复是TimedOut,响应时间为0ms。我的脚本是否导致错误超时?感谢。
编辑:更新的代码以反映最新的更改,仍然具有相同的行为。
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());
}
答案 0 :(得分:1)
如果您的ping -t
超时值小于1000或maxRoundTrip
的值小于1000,那么您将检查两个不同ping中的不同超时(.NET Ping.Send
vs 。ping -t
)。默认的Windows ping超时为4000毫秒。 http://technet.microsoft.com/en-us/library/bb490968.aspx
同样在.NET代码中,您发送的最大缓冲区大小为65500字节。默认的Windows ping命令仅发送32个字节的数据。
因此,超时或缓冲区大小之间的差异可能是造成差异的原因。
有关.NET Ping.Send方法的更多信息:http://msdn.microsoft.com/en-us/library/ms144956(v=vs.110).aspx
答案 1 :(得分:1)
我可能已经弄清楚了。我正在使用相关机器的netbios名称。我猜测每次进行ping操作都会考虑到往返的IP查找并超时。当我只使用IP时,它运行得很好并且没有超时。
感谢您的投入。
答案 2 :(得分:0)
在我的例子中,字节数组大小是主要原因(我编写了类似的ping应用程序)
何时
var buffer = new byte[65500];
2014/3/30 11:29:26 8.8.8.8:TimedOut(0ms)
更改为
var buffer = new byte[32];
2014/3/30 11:32:50 8.8.8.8:成功(8ms)
我推断ping缓冲区如果太高,那么ICMP echo消息可能被分段成为多个数据包然后只发送出去,因此它无法在超时期限内完成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());
}
}
}
}
var reply = ping.Send(h, 1000, buffer, new PingOptions(600, false));
1000是ping回复的超时(ms)...
答案 3 :(得分:0)
我看到的行为与OP相同。我的ping.Send()只发送一个byte [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");
}