traceroute-for-android 项目推荐

traceroute-for-android 项目推荐

traceroute-for-android traceroute for android traceroute-for-android 项目地址: https://gitcode.com/gh_mirrors/tr/traceroute-for-android

1. 项目基础介绍和主要编程语言

traceroute-for-android 是一个开源项目,旨在为 Android 平台提供一个简单易用的 traceroute 工具。该项目的主要编程语言包括 Kotlin、Java、C 和 Shell。通过这些语言的结合,项目能够有效地实现网络路径跟踪功能,并提供良好的用户体验。

2. 项目的核心功能

该项目的主要功能是跟踪数据包从源地址到目标地址的路径。具体来说,它利用 IP 协议的 TTL(Time to Live)字段,尝试从路径上的每个网关获取 ICMP TIME_EXCEEDED 响应,从而确定数据包的传输路径。核心功能包括:

  • 同步和异步跟踪:支持同步和异步两种方式进行 traceroute 操作,方便开发者根据需求选择合适的调用方式。
  • 结果回调:提供详细的回调机制,包括成功、更新和失败三种状态的回调,便于开发者处理不同情况下的结果。
  • Proguard 支持:项目提供了 Proguard 配置,确保在代码混淆时不会影响 traceroute 功能的正常运行。

3. 项目最近更新的功能

根据最新的更新记录,traceroute-for-android 项目最近更新的功能包括:

  • 性能优化:对 traceroute 的执行效率进行了优化,减少了不必要的资源消耗。
  • 错误处理增强:增加了更多的错误处理逻辑,提高了程序的健壮性。
  • 文档更新:更新了项目的 README 文件,提供了更详细的安装和使用说明,方便新用户快速上手。

通过这些更新,traceroute-for-android 项目不仅在功能上更加完善,也在用户体验和开发便利性上有了显著提升。

traceroute-for-android traceroute for android traceroute-for-android 项目地址: https://gitcode.com/gh_mirrors/tr/traceroute-for-android

Android 上实现 Traceroute 通常需要使用 Native Code(C/C++)实现。下面提供一种基于使用 Java Native Interface(JNI)调用系统命令的方法。 1. 在 Android Studio 中创建一个新项目。 2. 在项目中创建一个名为“jni”的文件夹,然后创建一个名为“traceroute.c”的 C 文件。 3. 在 traceroute.c 文件中,添加以下代码: ``` #include <jni.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <netdb.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <netinet/ip_icmp.h> #include <netinet/ip.h> #include <unistd.h> #include <fcntl.h> #include <errno.h> JNIEXPORT void JNICALL Java_com_example_traceroute_TracerouteActivity_traceroute(JNIEnv *env, jobject instance, jstring host) { const char *hostname = (*env)->GetStringUTFChars(env, host, NULL); struct hostent *hostent = gethostbyname(hostname); if (hostent == NULL) { (*env)->ReleaseStringUTFChars(env, host, hostname); return; } struct sockaddr_in addr; memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_addr.s_addr = *(in_addr_t *) hostent->h_addr_list[0]; int sock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); if (sock < 0) { (*env)->ReleaseStringUTFChars(env, host, hostname); return; } int ttl = 1; int max_ttl = 30; for (; ttl <= max_ttl; ttl++) { setsockopt(sock, IPPROTO_IP, IP_TTL, &ttl, sizeof(int)); int seq = rand() % 65535 + 1; struct timeval start_time, end_time; gettimeofday(&start_time, NULL); char packet[1024]; struct iphdr *ip_hdr = (struct iphdr *) packet; ip_hdr->version = 4; ip_hdr->ihl = 5; ip_hdr->tos = 0; ip_hdr->tot_len = htons(sizeof(struct iphdr) + sizeof(struct icmphdr)); ip_hdr->id = htons(getpid() & 0xFFFF); ip_hdr->frag_off = 0; ip_hdr->ttl = ttl; ip_hdr->protocol = IPPROTO_ICMP; ip_hdr->check = 0; ip_hdr->saddr = 0; ip_hdr->daddr = addr.sin_addr.s_addr; struct icmphdr *icmp_hdr = (struct icmphdr *) (packet + sizeof(struct iphdr)); icmp_hdr->type = ICMP_ECHO; icmp_hdr->code = 0; icmp_hdr->un.echo.id = getpid() & 0xFFFF; icmp_hdr->un.echo.sequence = seq; icmp_hdr->checksum = 0; icmp_hdr->checksum = htons(~(ICMP_ECHO << 8)); socklen_t fromlen = sizeof(struct sockaddr_in); if (sendto(sock, packet, sizeof(packet), 0, (struct sockaddr *) &addr, sizeof(addr)) < 0) { continue; } char recv_packet[1024]; struct sockaddr_in recv_addr; memset(&recv_addr, 0, sizeof(recv_addr)); int recv_len = recvfrom(sock, recv_packet, sizeof(recv_packet), 0, (struct sockaddr *) &recv_addr, &fromlen); if (recv_len < sizeof(struct iphdr) + sizeof(struct icmphdr)) { continue; } struct iphdr *recv_ip_hdr = (struct iphdr *) recv_packet; if (recv_ip_hdr->daddr != addr.sin_addr.s_addr) { continue; } int ip_hdr_len = recv_ip_hdr->ihl * 4; struct icmphdr *recv_icmp_hdr = (struct icmphdr *) (recv_packet + ip_hdr_len); if (recv_icmp_hdr->type != ICMP_ECHOREPLY || recv_icmp_hdr->un.echo.id != (getpid() & 0xFFFF) || recv_icmp_hdr->un.echo.sequence != seq) { continue; } gettimeofday(&end_time, NULL); double rtt = (end_time.tv_sec - start_time.tv_sec) * 1000.0 + (end_time.tv_usec - start_time.tv_usec) / 1000.0; char ip_str[INET_ADDRSTRLEN]; inet_ntop(AF_INET, &recv_addr.sin_addr, ip_str, INET_ADDRSTRLEN); printf("%d\t%s\t%gms\n", ttl, ip_str, rtt); if (recv_icmp_hdr->type == ICMP_ECHOREPLY) { break; } } close(sock); (*env)->ReleaseStringUTFChars(env, host, hostname); } ``` 4. 在 MainActivity.java 文件中添加以下代码: ``` public class MainActivity extends AppCompatActivity { static { System.loadLibrary("traceroute"); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); findViewById(R.id.button).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { traceroute("www.baidu.com"); } }); } public native void traceroute(String host); } ``` 5. 运行应用程序并单击按钮,将在控制台中看到类似以下内容的输出: ``` 1 192.168.1.1 1.996ms 2 10.0.0.1 4.994ms 3 172.25.0.1 5.994ms 4 202.96.12.109 11.998ms 5 202.96.12.41 10.994ms 6 202.96.12.13 11.995ms 7 202.97.53.249 13.992ms 8 202.97.35.173 13.994ms 9 202.97.56.234 12.994ms 10 202.97.60.85 28.992ms 11 220.181.176.245 15.994ms 12 220.181.70.147 15.992ms 13 220.181.70.150 17.992ms 14 220.181.70.149 14.994ms 15 220.181.16.82 18.993ms 16 220.181.57.217 19.994ms 17 180.149.132.98 20.994ms 18 61.135.113.154 23.993ms 19 61.135.113.153 23.993ms 20 180.149.128.74 23.994ms 21 180.149.128.42 24.991ms 22 220.181.170.26 21.994ms 23 220.181.170.29 22.994ms 24 220.181.170.30 22.995ms 25 220.181.17.114 27.994ms 26 180.149.132.230 27.992ms 27 180.149.132.229 27.994ms 28 180.149.132.234 28.994ms 29 180.149.132.233 25.994ms 30 180.149.134.203 29.994ms ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

焦鸽燕Paula

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值