WindivertDotnet快速发Ping( 二 )


/// <summary>/// 监听ping的回复/// </summary>/// <param name="cancellationToken">取消令牌</param>/// <returns></returns>private async Task<HashSet<IPAddress>> RecvEchoReplyAsync(CancellationToken cancellationToken){var results = new HashSet<IPAddress>();using var packet = new WinDivertPacket();using var addr = new WinDivertAddress();while (cancellationToken.IsCancellationRequested == false){try{await this.divert.RecvAsync(packet, addr, cancellationToken);if (TryGetEchoReplyAddr(packet, out var value)){results.Add(value);}// 把packet发出,避免系统其它软件此刻也有ping而收不到回复await this.divert.SendAsync(packet, addr, cancellationToken);}catch (OperationCanceledException){break;}}return results;}3.3 解析回复的IP/// <summary>/// 解析出icmp回复信息/// </summary>/// <param name="packet">数据包</param>/// <param name="value">回复的IP</param>/// <returns></returns>private unsafe static bool TryGetEchoReplyAddr(WinDivertPacket packet, [MaybeNullWhen(false)] out IPAddress value){var result = packet.GetParseResult();if (result.IcmpV4Header != null &&result.IcmpV4Header->Type == IcmpV4MessageType.EchoReply){value = https://www.huyubaike.com/biancheng/result.IPV4Header->SrcAddr;return true;}else if (result.IcmpV6Header != null &&result.IcmpV6Header->Type == IcmpV6MessageType.EchoReply){value = result.IPV6Header->SrcAddr;return true;}value = null;return false;}4 整合数据我们需要一个线程来开启接收ping回复,同时另一个线程把所有ping发出去,最后拿ping的所有IP和ping回复的所有IP求交集,就是我们需要的结果 。
/// <summary>/// Ping所有地址/// 占用两个线程/// </summary>/// <param name="dstAddrs">目标地址</param>/// <param name="delay">最后一个IP发出ping之后的等待回复时长</param>/// <returns></returns>public async Task<IPAddress[]> PingAllAsync(IEnumerable<IPAddress> dstAddrs, TimeSpan delay){// 开始监听ping的回复using var cts = new CancellationTokenSource();var recvTask = this.RecvEchoReplyAsync(cts.Token);// 对所有ip发pingawait this.SendEchoRequestAsync(dstAddrs);// 延时取消监听cts.CancelAfter(delay);var results = await recvTask;// 清洗数据return results.Intersect(dstAddrs).ToArray();}后记通过WindivertDotnet的路由,无中生有IP数据包,并可以将其正确的发送的指定的目的地IP地址 。像本示例的这个Ping方式,10秒ping完1万个IP并拿到其回复的IP是非常轻松的 。

经验总结扩展阅读