全球主机交流论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

CeraNetworks网络延迟测速工具IP归属甄别会员请立即修改密码
查看: 1057|回复: 11

[经验] 写了个优选IP程序

[复制链接]
发表于 2024-11-28 23:16:22 | 显示全部楼层 |阅读模式
本帖最后由 niconiconi 于 2024-12-8 18:39 编辑

写了个优选IP程序,实测50W个IP ping 4次取平均值,获取延迟最低前十只需要几秒钟,会动手的mjj自己编译,刚开始学有点糙

下载地址 https://drive.kamibook.com/raw/ipopt.7z

./ipopt.exe ipv4 ip.txt

ip.txt内容 示例 1.1.1.1/24  一行一个


  1. use std::{
  2.     result,
  3.     env,
  4.     net::IpAddr,
  5.     time::Duration,
  6.     io::BufRead,
  7.     collections::HashMap,
  8. };
  9. use futures::future::join_all;
  10. use rand::random;
  11. use surge_ping::{Client, Config, IcmpPacket, PingIdentifier, PingSequence, ICMP};
  12. use tokio::time;
  13. use ipnet::{Ipv4Net, Ipv6Net};

  14. #[tokio::main]
  15. async fn main() -> Result<(), Box<dyn std::error::Error>> {
  16.     let args: Vec<String> = env::args().collect();
  17.     let ips = get_ip_from_file(&args[2]).await?;
  18.     let ipaddrs = get_ip_range(&args[1], ips).await?;
  19.     let client_v4 = Client::new(&Config::default())?;
  20.     let client_v6 = Client::new(&Config::builder().kind(ICMP::V6).build())?;
  21.     let mut tasks = Vec::new();

  22.     for ip in &ipaddrs {
  23.         match ip.parse() {
  24.             Ok(IpAddr::V4(addr)) => {
  25.                 tasks.push(tokio::spawn(ping(client_v4.clone(), IpAddr::V4(addr))))

  26.             }
  27.             Ok(IpAddr::V6(addr)) => {
  28.                 tasks.push(tokio::spawn(ping(client_v6.clone(), IpAddr::V6(addr))))
  29.             }
  30.             Err(e) => println!("{} parse to ipaddr error: {}", ip, e),
  31.         }
  32.     }
  33.     let results: Vec<_> = join_all(tasks).await.into_iter().filter_map(Result::ok).collect();
  34.     let mut ip_map = HashMap::new();

  35.     for result in results {
  36.         match result {
  37.             Ok((ip, delay)) => {
  38.                 ip_map.insert(ip, delay);
  39.             }
  40.             Err(e) => {
  41.                 eprintln!("Error occurred: {:?}", e);
  42.             }
  43.         }
  44.     }
  45.     let mut top_10: Vec<_> = ip_map.into_iter()
  46.     .filter(|(_, delay)| delay.as_millis() > 0)
  47.     .collect::<Vec<_>>();
  48.     top_10.sort_by(|(_, delay1), (_, delay2)| delay1.cmp(delay2));
  49.     let top_10 = top_10.into_iter().take(10).collect::<Vec<_>>();

  50.     for (ip, delay) in top_10 {
  51.         println!("{} {:?}", ip, delay.as_millis());
  52.     }
  53.     Ok(())
  54. }
  55. async fn ping(client: Client, addr: IpAddr) -> Result<(IpAddr, Duration), Box<dyn std::error::Error + Send + 'static>> {    let payload = [0; 56];
  56.     let mut pinger = client.pinger(addr, PingIdentifier(random())).await;
  57.     let mut interval = time::interval(Duration::from_secs(1));
  58.     let mut delays = Vec::new();

  59.     for idx in 0..4 {
  60.         interval.tick().await;
  61.         match pinger.ping(PingSequence(idx), &payload).await {
  62.             Ok((IcmpPacket::V4(_packet), dur)) => {
  63.                 delays.push(dur);
  64.             }
  65.             Ok((IcmpPacket::V6(_packet), dur)) => {
  66.                 delays.push(dur);
  67.             }
  68.             Err(_e) => {
  69.             }
  70.         };
  71.     }
  72.     let average_delay = if !delays.is_empty() {
  73.         let total: Duration = delays.iter().sum();
  74.         total / delays.len() as u32
  75.     } else {
  76.         Duration::new(0, 0)
  77.     };
  78.     Ok((addr, average_delay))
  79. }

  80. async fn get_ip_from_file(file_path: &str) -> Result<Vec<String>, Box<dyn std::error::Error>> {
  81.     let mut ips = Vec::new();
  82.     let file = std::fs::File::open(file_path)?;
  83.     let mut buf_reader = std::io::BufReader::new(file);
  84.     let mut line = String::new();
  85.    
  86.     while buf_reader.read_line(&mut line).unwrap() > 0 {
  87.         let ip = line.trim();
  88.         ips.push(ip.to_string());
  89.         line.clear();
  90.     }
  91.     Ok(ips)
  92. }


  93. async fn get_ip_range(ip_type: &str, ips: Vec<String>) -> result::Result<Vec<String>, Box<dyn std::error::Error>> {
  94.     let mut ip_subnets = Vec::new();

  95.     match ip_type {
  96.         "ipv4" => {
  97.             for ip in ips {
  98.                 let net: Ipv4Net = ip.parse().unwrap();
  99.                 let subnets = net.subnets(32).expect("PrefixLenError: new prefix length cannot be shorter than existing");
  100.                 for (_i, n) in subnets.enumerate() {
  101.                     ip_subnets.push(n.to_string());
  102.                 }
  103.             }
  104.         }
  105.         "ipv6" => {
  106.             for ip in ips {
  107.                 let net: Ipv6Net = ip.parse().unwrap();
  108.                 let subnets = net.subnets(128).expect("PrefixLenError: new prefix length cannot be shorter than existing");
  109.                 for (_i, n) in subnets.enumerate() {
  110.                     ip_subnets.push(n.to_string());
  111.                 }
  112.             }
  113.         }
  114.         _ => {
  115.             return Err(Box::new(std::io::Error::new(std::io::ErrorKind::InvalidInput, "Invalid IP type")));
  116.         }
  117.     }
  118.     let ip_range: Vec<String> =  ip_subnets.into_iter().map(|subnet: String| subnet.split('/').next().unwrap().to_string()).collect();
  119.     Ok(ip_range)
  120. }
复制代码
发表于 2024-11-28 23:17:42 | 显示全部楼层
大佬怎么用呢?  
发表于 2024-11-28 23:18:43 | 显示全部楼层
不是有7Z吗 ,下载下来用啊
 楼主| 发表于 2024-11-28 23:27:36 | 显示全部楼层
由于多线程并发,会创建大量任务,这也是为什么在几秒钟内完成,所以cpu 内存会占用很大,50W占用内存800M
发表于 2024-11-29 00:00:51 | 显示全部楼层
loc还有会rust的,罕见
 楼主| 发表于 2024-11-29 00:26:27 来自手机 | 显示全部楼层
skysf 发表于 2024-11-29 00:00
loc还有会rust的,罕见

loc人才济济
发表于 2024-11-29 00:30:03 | 显示全部楼层
skysf 发表于 2024-11-29 00:00
loc还有会rust的,罕见


没什么罕见的,rust跟其他一样都是用库而已,你说看到.cpp .c那才叫罕见
发表于 2024-11-29 00:30:43 | 显示全部楼层
编译不通过
 楼主| 发表于 2024-11-29 00:32:19 来自手机 | 显示全部楼层
弟弟不爱吃饭 发表于 2024-11-29 00:30
编译不通过

错误截图
发表于 2024-11-29 03:31:37 | 显示全部楼层
loc果然高手如云啊
您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|小黑屋|全球主机交流论坛

GMT+8, 2024-12-28 06:17 , Processed in 0.060804 second(s), 6 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表