如何使用特定网络接口(或特定源 IP 地址)进行 Ping?

2023-12-08

根据这个链接:使用 System.Net.NetworkInformation,有没有办法将 ping 绑定到特定接口?ICMP 不能绑定到网络接口(与基于套接字的东西不同):

ICMP 不是基于套接字的。 ping 将根据路由表发送到适当的端口。https://stackoverflow.com/editing-help

但我看不到任何正确的方法来获取有关“pinger”的信息。至少,在 shell 命令中我可以指定源 IP 地址,但在使用 Ping 类时则不能。

我尝试以编程方式执行一些跟踪路由来获取 Ping 路由中涉及的 IP 地址,但我没有获取网络接口的 IP 地址(我猜这是因为我无法将 TTL 设置为 0)。

知道如何确定某个 ping 使用哪个网络接口吗? (或者指定用于 ping 的网络接口的方法)。


i know this is a old question but i found a solution and want to share it.

我将其发布在 CodeProject 上,这是链接:http://www.codeproject.com/Questions/828234/Ping-over-specific-Interface-with-IcmpSendEchoEx?loginkey=false

Edited:

所以解决方案是使用Iphlpapi.dll中的IcmpSendEcho2Ex函数。

此函数使用接口 ip 地址来确定应在哪个接口上发送 ping。

该链接包括 p 调用和包装函数输出的回复类。


来自代码项目的代码:

public static PingReply Send(IPAddress srcAddress, IPAddress destAddress, int timeout = 5000, byte[] buffer = null, PingOptions po = null)
{
    if (destAddress == null || destAddress.AddressFamily != AddressFamily.InterNetwork || destAddress.Equals(IPAddress.Any))
        throw new ArgumentException();
 
    //Defining pinvoke args
    var source = srcAddress == null ? 0 : BitConverter.ToUInt32(srcAddress.GetAddressBytes(), 0);
    var destination = BitConverter.ToUInt32(destAddress.GetAddressBytes(), 0);
    var sendbuffer = buffer ?? new byte[] {};
    var options = new Interop.Option
    {
        Ttl = (po == null ? (byte) 255 : (byte) po.Ttl),
        Flags = (po == null ? (byte) 0 : po.DontFragment ? (byte) 0x02 : (byte) 0) //0x02
    };
    var fullReplyBufferSize = Interop.ReplyMarshalLength + sendbuffer.Length; //Size of Reply struct and the transmitted buffer length.

 

    var allocSpace = Marshal.AllocHGlobal(fullReplyBufferSize); // unmanaged allocation of reply size. TODO Maybe should be allocated on stack
    try
    {
        DateTime start = DateTime.Now;
        var nativeCode = Interop.IcmpSendEcho2Ex(
            Interop.IcmpHandle, //_In_      HANDLE IcmpHandle,
            default(IntPtr), //_In_opt_  HANDLE Event,
            default(IntPtr), //_In_opt_  PIO_APC_ROUTINE ApcRoutine,
            default(IntPtr), //_In_opt_  PVOID ApcContext
            source, //_In_      IPAddr SourceAddress,
            destination, //_In_      IPAddr DestinationAddress,
            sendbuffer, //_In_      LPVOID RequestData,
            (short) sendbuffer.Length, //_In_      WORD RequestSize,
            ref options, //_In_opt_  PIP_OPTION_INFORMATION RequestOptions,
            allocSpace, //_Out_     LPVOID ReplyBuffer,
            fullReplyBufferSize, //_In_      DWORD ReplySize,
            timeout //_In_      DWORD Timeout
            );
        TimeSpan duration = DateTime.Now - start;
        var reply = (Interop.Reply) Marshal.PtrToStructure(allocSpace, typeof (Interop.Reply)); // Parse the beginning of reply memory to reply struct

        byte[] replyBuffer = null;
        if (sendbuffer.Length != 0)
        {
            replyBuffer = new byte[sendbuffer.Length];
            Marshal.Copy(allocSpace + Interop.ReplyMarshalLength, replyBuffer, 0, sendbuffer.Length); //copy the rest of the reply memory to managed byte[]
        }
 
        if (nativeCode == 0) //Means that native method is faulted.
            return new PingReply(nativeCode, reply.Status, new IPAddress(reply.Address), duration);
        else
            return new PingReply(nativeCode, reply.Status, new IPAddress(reply.Address), reply.RoundTripTime, replyBuffer);
    }
    finally
    {
        Marshal.FreeHGlobal(allocSpace); //free allocated space
    }
}
 
/// <summary>Interoperability Helper
///     <see cref="http://msdn.microsoft.com/en-us/library/windows/desktop/bb309069(v=vs.85).aspx" />
/// </summary>
private static class Interop
{
    private static IntPtr? icmpHandle;
    private static int? _replyStructLength;
 
    /// <summary>Returns the application legal icmp handle. Should be close by IcmpCloseHandle
    ///     <see cref="http://msdn.microsoft.com/en-us/library/windows/desktop/aa366045(v=vs.85).aspx" />
    /// </summary>
    public static IntPtr IcmpHandle
    {
        get
        {
            if (icmpHandle == null)
            {
                icmpHandle = IcmpCreateFile();
                //TODO Close Icmp Handle appropiate
            }
 
            return icmpHandle.GetValueOrDefault();
        }
    }
    /// <summary>Returns the the marshaled size of the reply struct.</summary>
    public static int ReplyMarshalLength
    {
        get
        {
            if (_replyStructLength == null)
            {
                _replyStructLength = Marshal.SizeOf(typeof (Reply));
            }
            return _replyStructLength.GetValueOrDefault();
        }
    }
 

    [DllImport("Iphlpapi.dll", SetLastError = true)]
    private static extern IntPtr IcmpCreateFile();
    [DllImport("Iphlpapi.dll", SetLastError = true)]
    private static extern bool IcmpCloseHandle(IntPtr handle);
    [DllImport("Iphlpapi.dll", SetLastError = true)]
    public static extern uint IcmpSendEcho2Ex(IntPtr icmpHandle, IntPtr Event, IntPtr apcroutine, IntPtr apccontext, UInt32 sourceAddress, UInt32 destinationAddress, byte[] requestData, short requestSize, ref Option requestOptions, IntPtr replyBuffer, int replySize, int timeout);
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct Option
    {
        public byte Ttl;
        public readonly byte Tos;
        public byte Flags;
        public readonly byte OptionsSize;
        public readonly IntPtr OptionsData;
    }
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct Reply
    {
        public readonly UInt32 Address;
        public readonly int Status;
        public readonly int RoundTripTime;
        public readonly short DataSize;
        public readonly short Reserved;
        public readonly IntPtr DataPtr;
        public readonly Option Options;
    }
}

[Serializable]
public class PingReply
{
    private readonly byte[] _buffer = null;
    private readonly IPAddress _ipAddress = null;
    private readonly uint _nativeCode = 0;
    private readonly TimeSpan _roundTripTime = TimeSpan.Zero;
    private readonly IPStatus _status = IPStatus.Unknown;
    private Win32Exception _exception;
 

    internal PingReply(uint nativeCode, int replystatus, IPAddress ipAddress, TimeSpan duration)
    {
        _nativeCode = nativeCode;
        _ipAddress = ipAddress;
        if (Enum.IsDefined(typeof (IPStatus), replystatus))
            _status = (IPStatus) replystatus;
    }
    internal PingReply(uint nativeCode, int replystatus, IPAddress ipAddress, int roundTripTime, byte[] buffer)
    {
        _nativeCode = nativeCode;
        _ipAddress = ipAddress;
        _roundTripTime = TimeSpan.FromMilliseconds(roundTripTime);
        _buffer = buffer;
        if (Enum.IsDefined(typeof (IPStatus), replystatus))
            _status = (IPStatus) replystatus;
    }
 

    /// <summary>Native result from <code>IcmpSendEcho2Ex</code>.</summary>
    public uint NativeCode
    {
        get { return _nativeCode; }
    }
    public IPStatus Status
    {
        get { return _status; }
    }
    /// <summary>The source address of the reply.</summary>
    public IPAddress IpAddress
    {
        get { return _ipAddress; }
    }
    public byte[] Buffer
    {
        get { return _buffer; }
    }
    public TimeSpan RoundTripTime
    {
        get { return _roundTripTime; }
    }
    /// <summary>Resolves the <code>Win32Exception</code> from native code</summary>
    public Win32Exception Exception
    {
        get
        {
            if (Status != IPStatus.Success)
                return _exception ?? (_exception = new Win32Exception((int) NativeCode, Status.ToString()));
            else
                return null;
        }
    }
 
    public override string ToString()
    {
        if (Status == IPStatus.Success)
            return Status + " from " + IpAddress + " in " + RoundTripTime + " ms with " + Buffer.Length + " bytes";
        else if (Status != IPStatus.Unknown)
            return Status + " from " + IpAddress;
        else
            return Exception.Message + " from " + IpAddress;
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用特定网络接口(或特定源 IP 地址)进行 Ping? 的相关文章

  • 如何将 std::string& 转换为 C# 引用字符串

    我正在尝试将 C 函数转换为std string参考C 我的 API 如下所示 void GetStringDemo std string str 理想情况下 我希望在 C 中看到类似的东西 void GetStringDemoWrap r
  • C# 异步等待澄清?

    我读了here http blog stephencleary com 2012 02 async and await html that 等待检查等待的看看它是否有already完全的 如果 可等待已经完成 那么该方法将继续 运行 同步
  • std::vector 与 std::stack

    有什么区别std vector and std stack 显然 向量可以删除集合中的项目 尽管比列表慢得多 而堆栈被构建为仅后进先出的集合 然而 堆栈对于最终物品操作是否更快 它是链表还是动态重新分配的数组 我找不到关于堆栈的太多信息 但
  • 如何在 C# 中打开 Internet Explorer 属性窗口

    我正在开发一个 Windows 应用程序 我必须向用户提供一种通过打开 IE 设置窗口来更改代理设置的方法 Google Chrome 使用相同的方法 当您尝试更改 Chrome 中的代理设置时 它将打开 Internet Explorer
  • C++ 多行字符串原始文字[重复]

    这个问题在这里已经有答案了 我们可以像这样定义一个多行字符串 const char text1 part 1 part 2 part 3 part 4 const char text2 part 1 part 2 part 3 part 4
  • 在 Unity 中实现 Fur with Shells 技术

    我正在尝试在 Unity 中实现皮毛贝壳技术 http developer download nvidia com SDK 10 5 direct3d Source Fur doc FurShellsAndFins pdf Fins 技术被
  • 使用 C# 中的 CsvHelper 将不同文化的 csv 解析为十进制

    C 中 CsvHelper 解析小数的问题 我创建了一个从 byte 而不是文件获取 csv 文件的类 并且它工作正常 public static List
  • 如何获取 EF 中与组合(键/值)列表匹配的记录?

    我有一个数据库表 其中包含每个用户 年份组合的记录 如何使用 EF 和用户 ID 年份组合列表从数据库获取数据 组合示例 UserId Year 1 2015 1 2016 1 2018 12 2016 12 2019 3 2015 91
  • 结构体的内存大小不同?

    为什么第一种情况不是12 测试环境 最新版本的 gcc 和 clang 64 位 Linux struct desc int parts int nr sizeof desc Output 16 struct desc int parts
  • C# xml序列化必填字段

    我需要将一些字段标记为需要写入 XML 文件 但没有成功 我有一个包含约 30 个属性的配置类 这就是为什么我不能像这样封装所有属性 public string SomeProp get return someProp set if som
  • C 编程:带有数组的函数

    我正在尝试编写一个函数 该函数查找行为 4 列为 4 的二维数组中的最大值 其中二维数组填充有用户输入 我知道我的主要错误是函数中的数组 但我不确定它是什么 如果有人能够找到我出错的地方而不是编写新代码 我将不胜感激 除非我刚去南方 我的尝
  • 空指针与 int 等价

    Bjarne 在 C 编程语言 中写道 空指针与整数零不同 但 0 可以用作空指针的指针初始值设定项 这是否意味着 void voidPointer 0 int zero 0 int castPointer reinterpret cast
  • C# 动态/expando 对象的深度/嵌套/递归合并

    我需要在 C 中 合并 2 个动态对象 我在 stackexchange 上找到的所有内容仅涵盖非递归合并 但我正在寻找能够进行递归或深度合并的东西 非常类似于jQuery 的 extend obj1 obj2 http api jquer
  • 如何实例化 ODataQueryOptions

    我有一个工作 简化 ODataController用下面的方法 public class MyTypeController ODataController HttpGet EnableQuery ODataRoute myTypes pub
  • 有没有办法让 doxygen 自动处理未记录的 C 代码?

    通常它会忽略未记录的 C 文件 但我想测试 Callgraph 功能 例如 您知道在不更改 C 文件的情况下解决此问题的方法吗 设置变量EXTRACT ALL YES在你的 Doxyfile 中
  • 为什么C++代码执行速度比java慢?

    我最近用 Java 编写了一个计算密集型算法 然后将其翻译为 C 令我惊讶的是 C 的执行速度要慢得多 我现在已经编写了一个更短的 Java 测试程序和一个相应的 C 程序 见下文 我的原始代码具有大量数组访问功能 测试代码也是如此 C 的
  • C++ 中的 include 和 using 命名空间

    用于使用cout 我需要指定两者 include
  • 指针和内存范围

    我已经用 C 语言编程有一段时间了 但对 C 语言还是很陌生 有时我对 C 处理内存的方式感到困惑 考虑以下有效的 C 代码片段 const char string void where is this pointer variable l
  • 类型或命名空间“MyNamespace”不存在等

    我有通常的类型或命名空间名称不存在错误 除了我引用了程序集 using 语句没有显示为不正确 并且我引用的类是公共的 事实上 我在不同的解决方案中引用并使用相同的程序集来执行相同的操作 并且效果很好 顺便说一句 这是VS2010 有人有什么
  • 现代编译器是否优化乘以 1 和 -1

    如果我写 template

随机推荐

  • Flutter 升级 Flutter 版本后运行 pod install 时出错

    flutter版本升级到最新的Flutter 2 2 1后 在ios模拟器上运行app时 运行pod install时报错 我尝试通过执行以下命令来清洁 Pod 但它没有解决问题 flutter clean flutter pub get
  • 将委托作为变量存储/传递

    我对 C 相当陌生 正在研究一种使用串行通信来实现动态 GUI 的方法 我是C出身 所以函数指针的概念很熟悉 基本上我想在处理串行命令时调用answerFunction 函数 理论上 我有一个类 lbl txtBox Pair 它是在运行时
  • 可以从服务中检测到后退按钮按下吗?

    可以从服务中检测到后退按钮按下吗 真的如标题所说吗 我已经做了很多谷歌搜索 但找不到明确的答案 也没有办法做到吗 可以从服务中检测到后退按钮按下吗 不 抱歉 如果您在前台有一个 Activity 该 Activity 可以检测到 BACK
  • WordPress - 向 wp_posts 添加额外的列,然后发布到其中

    我试图在 添加帖子 或 添加页面 中添加一个额外的字段 我将该字段的值插入到数据库中 wp posts 表中添加的手动添加的列中 我知道我可以使用自定义字段模板 但问题是这些自定义字段将值插入 wp postmeta 而不是 wp post
  • 从 StackPanel 中删除子项

    for int i 0 i lt stackPanel Children Count i stackPanel Children Remove stackPanel Children i int x stackPanel Children
  • 访问 HttpParams 的所有条目

    有没有一种方法可以迭代所有条目HttpParams object 其他人也有类似的问题 打印 HttpParams HttpUriRequest 的内容 但答案并没有真正起作用 当调查时基本Http参数我看到有一个HashMap里面 但无法
  • 在 virtualenv 中的 GPU 集群上运行 TensorFlow

    我按照这些在 virtualenv 中安装了 GPU 版本的张量流指示 问题是 我在启动会话时遇到分段错误 也就是说 这段代码 import tensorflow as tf sess tf InteractiveSession 退出并出现
  • Debian 没有名为 numpy 的模块

    我已经在 Debian 上安装了 Python Numpy 使用 apt get 安装 python numpy 但是当运行 Python shell 时 我得到以下信息 Python 2 7 10 default Sep 9 2015 2
  • @Injectable() 装饰器和提供者数组

    Injectable 装饰器中 root 中提供的服务是否仍然必须位于模块的提供者数组中 The 角度文档并没有真正给我答案或者我不太明白 在我的核心文件夹中 我有一个在根目录中提供的身份验证服务 我不想将我的核心模块导入到应用程序模块中
  • React 将历史记录传递给路由器中定义的组件

    我的 App js 中有这个路由器
  • 如何更改默认 backBarButtonItem 上的颜色/图像?

    我需要更改默认的 self navigationItem backBarButtonItem 的颜色 为了实现这一点 我创建了一个自定义 Button 类并按如下方式实现它 void viewDidLoad super viewDidLoa
  • MVC3 在重定向到操作时销毁会话

    我在 MVC3 应用程序中遇到会话问题 在一个控制器中 我收到一个发布请求 然后在重定向到控制器 get 方法之前将值添加到会话中 问题是 在 GET 请求中 会话值返回 null 即使在 POST 请求中设置了会话值 HttpPost p
  • 带有复选框问题的 jQuery 禁用按钮

    我有以下代码 在选中复选框时启用按钮 http jsfiddle net ERfWz 1 以下是我的 HTML 页面中的代码片段 它非常相似 但由于某种原因它不起作用 我想我可能已经看它太久了
  • SmoothState.Js 页面更改后重新初始化页面脚本

    我使用 SmoothState js 进行页面转换 它工作正常并使用 ajax 加载新页面 然而 我在每个页面上都有需要重新初始化的 JS 脚本 并且我无法让它们始终出现在页面转换中 根据常见问题解答 smoothState js 提供了
  • 如何创建一个新对象,其中键作为一个对象的值,该对象作为值?

    我的问题有点类似于this 我有一个映射 其键为 objectType1 值为 objectType1 无效的 type ObjectType1 key string value string const newMap new Map
  • 在网页中嵌入 Windows 窗体用户控件的步骤

    我正在 Visual Studio 2005 中开发一个 Windows 窗体用户控件 它是一个文件上传控件 仅使用 2 个元素 显示 openfiledialog 的按钮 打开文件对话框 我已经在 html 页面中添加了一个带有类 id
  • Hibernate EntityManager.merge() 不更新数据库

    我有一个使用 Hibernate 的 Spring MVC Web 应用程序 我的问题是em merge拨打电话后没有回复 这是我的控制器 RequestMapping value updDep method RequestMethod P
  • 从 Mysql DB 填充 JFreechart TimeSeriesCollection?

    我正在尝试在我的应用程序中制作一个图表 该图表可以返回几个月内各天的温度 该图表是 JFreechart TimeSeriesCollection 我无法让该图表从数据库读取正确的数据 它显示了一些值 但不是全部 并且不显示正确的时间 为了
  • 为什么 gc() 不释放内存?

    我在一个上运行模拟Windows 64 位计算机 with 64 GB 内存 内存使用达到55 完成模拟运行后 我通过以下方式删除工作空间中的所有对象rm list ls 后面跟着一个double gc 我认为这将为下一次模拟运行释放足够的
  • 如何使用特定网络接口(或特定源 IP 地址)进行 Ping?

    根据这个链接 使用 System Net NetworkInformation 有没有办法将 ping 绑定到特定接口 ICMP 不能绑定到网络接口 与基于套接字的东西不同 ICMP 不是基于套接字的 ping 将根据路由表发送到适当的端口