.net 为什么新的PingReply不可能?

31moq8wy  于 2023-05-08  发布在  .NET
关注(0)|答案(2)|浏览(122)

当使用System.Net.NetworkInformation.Ping对象的SendPingAsync方法时,当尝试ping一个无法解析的主机名(即localhostnowhere)。
但是当捕获异常时,不可能新建一个PingReply?

PingReply pingReply = null;
  try
  {
    pingReply = await pingSender.SendPingAsync(host, timeout, buffer, options);
  }
  catch (PingException ex)
  {
    pingReply = new PingReply();
    //other pingReply properties set here, like status <> success, etc
  }
  catch (ArgumentNullException) { }
  catch (Exception) { throw; }

在查看PingReply的定义时,它没有默认的构造函数。它没有任何构造函数。

#region Assembly System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
// C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\System.dll
#endregion

namespace System.Net.NetworkInformation
{
  //
  // Summary:
  //     Provides information about the status and data resulting from a Overload:System.Net.NetworkInformation.Ping.Send
  //     or Overload:System.Net.NetworkInformation.Ping.SendAsync operation.
  public class PingReply
  {
    //
    // Summary:
    //     Gets the status of an attempt to send an Internet Control Message Protocol (ICMP)
    //     echo request and receive the corresponding ICMP echo reply message.
    //
    // Returns:
    //     An System.Net.NetworkInformation.IPStatus value indicating the result of the
    //     request.
    public IPStatus Status { get; }
    //
    // Summary:
    //     Gets the address of the host that sends the Internet Control Message Protocol
    //     (ICMP) echo reply.
    //
    // Returns:
    //     An System.Net.IPAddress containing the destination for the ICMP echo message.
    public IPAddress Address { get; }
    //
    // Summary:
    //     Gets the number of milliseconds taken to send an Internet Control Message Protocol
    //     (ICMP) echo request and receive the corresponding ICMP echo reply message.
    //
    // Returns:
    //     An System.Int64 that specifies the round trip time, in milliseconds.
    public long RoundtripTime { get; }
    //
    // Summary:
    //     Gets the options used to transmit the reply to an Internet Control Message Protocol
    //     (ICMP) echo request.
    //
    // Returns:
    //     A System.Net.NetworkInformation.PingOptions object that contains the Time to
    //     Live (TTL) and the fragmentation directive used for transmitting the reply if
    //     System.Net.NetworkInformation.PingReply.Status is System.Net.NetworkInformation.IPStatus.Success;
    //     otherwise, null.
    public PingOptions Options { get; }
    //
    // Summary:
    //     Gets the buffer of data received in an Internet Control Message Protocol (ICMP)
    //     echo reply message.
    //
    // Returns:
    //     A System.Byte array containing the data received in an ICMP echo reply message,
    //     or an empty array, if no reply was received.
    public byte[] Buffer { get; }
  }
}

如果ping不成功,如何返回PingReply?Ping如何返回新的PingReply?

u3r8eeie

u3r8eeie1#

PingReply构造函数被定义为内部和
内部类型或成员只能在同一程序集https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/internal中的文件内访问
这样你就不能调用它们,因为你的代码不在同一个程序集中,而Ping在同一个程序集中。
如果根本没有执行SendPingAsync,则会出现异常。如果已执行,您可以检查pingReply.Status。

cunj1qz1

cunj1qz12#

我也有一个理由要创建PingReply对象。在我的例子中,我有一些例程将PingReply对象作为参数,我想为它们创建单元测试。最终我发现这可以用C#反射来完成。
在进一步讨论之前,我要补充一点,像这样覆盖类作者的意图通常不是一个好主意,但对于像我这样的业余爱好者来说,出于单元测试的目的,我认为这可能是可以的。
下面是我编写的一个类,它将创建任意的PingReply对象:

public static class NewPingReply {
  public static PingReply Create(IPAddress address, PingOptions? options,
    IPStatus ipStatus, long rtt, byte[] buffer) 
  {
    var args = new object?[5] {address, options, ipStatus, rtt, buffer};
    var types = new Type[5] {typeof(IPAddress), typeof(PingOptions), 
      typeof(IPStatus), typeof(long), typeof(byte[])};
    var conInfo = typeof(PingReply)
      .GetConstructor(BindingFlags.Instance|BindingFlags.NonPublic, types);
    var newObj = conInfo?.Invoke(args);
    return newObj is PingReply pr ? pr : throw new Exception("failure to create PingReply");
  }
}

您可以按如下方式调用它,当然使用您想要的参数:

PingReply timedOutPingReply = NewPingReply.Create(IPAddress.Parse("10.1.1.1"),
                                    null, IPStatus.TimedOut, 0, Array.Empty<byte>());

参考文献:

相关问题