Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# .NET Ping()提供错误的超时?_C#_.net_Network Programming_Ping - Fatal编程技术网

C# .NET Ping()提供错误的超时?

C# .NET Ping()提供错误的超时?,c#,.net,network-programming,ping,C#,.net,Network Programming,Ping,我有一个脚本,它每秒循环并向主机发送一个ping。其目的是在我的家庭网络上测试无线性能。问题是,我的脚本似乎有超时,而任何一个客户端(pingER和pingEE)上的标准“ping-t”都没有超时。事实上,在过去30分钟内,没有一次超时,而我的脚本每隔几分钟就会收到超时回复 我的基本脚本如下。在所有情况下,当它发生时,我的答复是TimedOut,响应时间为0毫秒。我的脚本是否导致错误超时?谢谢 编辑:更新代码以反映最新的更改,仍然具有相同的行为 while (true) { System

我有一个脚本,它每秒循环并向主机发送一个ping。其目的是在我的家庭网络上测试无线性能。问题是,我的脚本似乎有超时,而任何一个客户端(pingER和pingEE)上的标准“ping-t”都没有超时。事实上,在过去30分钟内,没有一次超时,而我的脚本每隔几分钟就会收到超时回复

我的基本脚本如下。在所有情况下,当它发生时,我的答复是TimedOut,响应时间为0毫秒。我的脚本是否导致错误超时?谢谢

编辑:更新代码以反映最新的更改,仍然具有相同的行为

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中的不同超时情况(.NET
ping.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)中运行.NET
Ping.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");
}