• 显示dos命令ping和tracert等输出结果中的ip对应的地域名称


      公司老大今天使用了dos命令ping,他想看到其中ip地址对应的地域名称。

      如dos下命令ping www.qq.com的输出结果是:

    正在 Ping www.qq.com [113.108.20.50] 具有 32 字节的数据:

    正在 Ping www.qq.com [113.108.20.50] 具有 32 字节的数据:
    来自 113.108.20.50 的回复: 字节=32 时间=3ms TTL=52
    来自 113.108.20.50 的回复: 字节=32 时间=3ms TTL=52
    来自 113.108.20.50 的回复: 字节=32 时间=2ms TTL=52
    来自 113.108.20.50 的回复: 字节=32 时间=3ms TTL=52


    113.108.20.50 的 Ping 统计信息:
        数据包: 已发送 = 4,已接收 = 4,丢失 = 0 (0% 丢失),
    往返行程的估计时间(以毫秒为单位):

        最短 = 2ms,最长 = 3ms,平均 = 2ms

      如果上面的输出结果中每个ip后面跟着相应的地域名称是不是更好点?

      老大给了一个url  https://www.surfchen.org/nali,这位老兄使用了纯真ip数据库,给出了linux下的相应实现。

      有了相应的参考,我们便可以实现windows下的相应实现了,详细步骤如下:

      1 创建匿名管道,截获相应dos命令输出结果的每一行的字符串,如果输出为空,则退出,否则进行下面步骤;

      2 提取出字符串中的ip地址,如果没有ip地址,直接跳到第5步;

      3 调用纯真ip数据库的相关接口获取相应的地域名称;

      4 把地域名称字符串插入到原字符串的后面,形成新字符串,输出;

      5回到第一步。

      上面的关键在于创建匿名管道,然后截取字符串中的ip地址。

      我使用了VC2010创建了相关工程,如果要在Debug模式下进行调试,注意把数据库QQWry.Dat复制到工程的Debug目录下面。

      发布的时候,把程序tr.exe和QQWry.Dat放在一个目录下发布,其使用格式是tr dos command 或 tr.exe dos command,如tr ping www.qq.com,其结果如下:

    正在 Ping www.qq.com [113.108.20.50  广东省深圳市 电信] 具有 32 字节的数据:
    来自 113.108.20.50  广东省深圳市 电信 的回复: 字节=32 时间=3ms TTL=52
    来自 113.108.20.50  广东省深圳市 电信 的回复: 字节=32 时间=3ms TTL=52
    来自 113.108.20.50  广东省深圳市 电信 的回复: 字节=32 时间=3ms TTL=52
    来自 113.108.20.50  广东省深圳市 电信 的回复: 字节=32 时间=3ms TTL=52

      如果要输出命令tracert的结果相关地域名称,使用命令就是tr tracert www.qq.com 或 tr.exe tracert www.qq.com。

      我的email是alexstocks@foxmail.com,欢迎要程序或者报告bug。

      一些关键的源码如下:

      

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include "./qqwry.h"
    #include <Windows.h>

    #define NALI_QQWRY_PATH "./QQWry.Dat"

    #define PIPE_BUFFER_SIZE 1024
    typedef struct pipe_info_tag {
    HANDLE pipe;
    char buffer[PIPE_BUFFER_SIZE];
    } pipe_info_t;

    pipe_info_t pipe_out = {INVALID_HANDLE_VALUE, "\0"};
    pipe_info_t pipe_err = {INVALID_HANDLE_VALUE, "\0"};

    unsigned int get_host_ip(char* str, char** ip_start, char** ip_end, char* ip);
    unsigned int get_ip_city_string(char* ip);
    unsigned int read_from_pipe(void* args);

    int main(int argc, char *argv[])
    {
    HANDLE cur_proc_handle = NULL;
    HANDLE pipe_handle = NULL;
    HANDLE pipe_thread[2] = {NULL, NULL};
    PROCESS_INFORMATION proc_info;
    SECURITY_ATTRIBUTES security_attr;
    STARTUPINFO start_info;
    char cmd_line[1024] = {0};
    int ret = 0;
    char err_msg[1024] = {0};
    unsigned int thread_id = 0;
    int idx = 0;

    cur_proc_handle = GetCurrentProcess();
    memset(&proc_info, 0, sizeof(proc_info));
    memset(&security_attr, 0, sizeof(security_attr));
    memset(&start_info, 0, sizeof(start_info));

    start_info.cb = sizeof(STARTUPINFO);
    start_info.dwFlags = STARTF_USESTDHANDLES;
    start_info.hStdInput = INVALID_HANDLE_VALUE;

    security_attr.nLength = sizeof(SECURITY_ATTRIBUTES);
    security_attr.lpSecurityDescriptor = NULL;
    security_attr.bInheritHandle = TRUE;

    CreatePipe(&(pipe_out.pipe), &pipe_handle, &security_attr, 0);
    DuplicateHandle(cur_proc_handle, pipe_handle, cur_proc_handle, &(start_info.hStdOutput), 0, TRUE, DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);


    CreatePipe(&(pipe_err.pipe), &pipe_handle, &security_attr, 0);
    DuplicateHandle(cur_proc_handle, pipe_handle, cur_proc_handle, &(start_info.hStdOutput), 0, TRUE, DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);

    strcpy(cmd_line, "");
    for (idx = 1; idx < argc; idx++) {
    strcat(cmd_line, argv[idx]);
    strcat(cmd_line, " ");
    }
    if (0 == strlen(cmd_line)) {
    strcpy(cmd_line, "ping www.qq.com");
    }
    ret = CreateProcess(NULL, cmd_line, NULL, NULL, TRUE, DETACHED_PROCESS, NULL, NULL, &start_info, &proc_info);
    if (ret == 0) {
    unsigned int err_no = GetLastError();
    int err_msg_len = _snprintf(err_msg, sizeof(err_msg) - 1, "Tried to launch: \"%s\", but get error [%u]: ", cmd_line, err_no);
    FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_MAX_WIDTH_MASK, NULL, err_no, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), &err_msg[err_msg_len], 0, NULL);
    return 1;
    }

    CloseHandle(start_info.hStdOutput);
    CloseHandle(start_info.hStdError);

    WaitForInputIdle(proc_info.hProcess, 5000);
    CloseHandle(proc_info.hThread);

    pipe_thread[0] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)read_from_pipe, &pipe_out, 0, (LPDWORD)&thread_id);
    pipe_thread[0] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)read_from_pipe, &pipe_err, 0, (LPDWORD)&thread_id);

    WaitForSingleObject(proc_info.hProcess, INFINITE);
    CloseHandle(proc_info.hProcess);

    WaitForMultipleObjects(2, pipe_thread, TRUE, INFINITE);
    CloseHandle(pipe_thread[0]);
    CloseHandle(pipe_thread[1]);

    return 0;
    }


    unsigned int read_from_pipe(void* args) {
    pipe_info_t* pipe_info = (pipe_info_t*)(args);
    char* last_buf = NULL;
    unsigned int read = 0;
    int ret = 0;
    char tmp_buf[1024] = {0};
    char buf[1024] = {0};
    char pre_ip_string[1024] = {0};
    char post_ip_string[1024] = {0};
    char ip_string[1024] = {0};
    char ip[10] = {0};
    char* ip_start = NULL;
    char* ip_end = NULL;
    if (NULL == args) {
    return 1;
    }

    while (1) {
    memset(ip, 0, sizeof(ip));
    ret = ReadFile(pipe_info->pipe, buf, sizeof(buf), (LPDWORD)&read, 0L);
    if (ret == 0 || read == 0) {
    CloseHandle(pipe_info->pipe);
    break;
    }
    buf[read] = '\0';
    //printf("%s", buf);
    memset(tmp_buf, 0, sizeof(tmp_buf));
    memset(ip, 0, sizeof(ip));
    ret = get_host_ip(buf, &ip_start, &ip_end, ip);
    if (ret == 1 && NULL != ip_end) {
    memset(tmp_buf, 0, sizeof(tmp_buf));
    memcpy(tmp_buf, buf, ip_end - buf);
    printf("%s", tmp_buf);
    get_ip_city_string(ip);
    printf("%s", ip_end);
    } else {
    printf("%s", buf);
    }
    }

    return 0;
    }

    unsigned int get_host_ip(char* str, char** ip_start, char** ip_end, char* ip) {
    char buf[4] = {0};
    int runnum = 0;
    int ret = 0;
    int idx = 0;
    int start = 0;
    int str_len = strlen(str);
    int num = 0;
    int ip_idx = 0;
    int ip_num[32] = {0};

    while (1) {
    *ip_start = NULL;
    *ip_end = NULL;
    runnum++;
    //get the first number index
    if (1 < runnum) {
    ret = 0;
    for (idx = start + 1; idx < str_len; idx++) {
    if (str[idx] < '1' || '9' < str[idx]) {
    start = idx;
    *ip_start = str + idx;
    ret = 1;
    break;
    }
    }

    if (ret == 0) {
    break;
    }
    }

    //get the first number index
    ret = 0;
    for (idx = start; idx < str_len; idx++) {
    if ('1' <= str[idx] && str[idx] <= '9') {
    start = idx;
    *ip_start = str + idx;
    ret = 1;
    break;
    }
    }

    if (ret == 0) {
    break;
    }

    //check whether there are three "."
    num = 0;
    for (idx = start; idx < str_len; idx++) {
    if (str[idx] == '.') {
    num++;
    }
    }
    if (num < 3) {
    ret = 0;
    break;
    }

    ret = 0;
    memset(buf, 0, sizeof(buf));
    for (idx = start, ip_idx = 0, num = 0; idx < str_len; idx++) {
    //get ip number string, its max length is 3
    if ('0' <= str[idx] && str[idx] <= '9') {
    if (num < 3) {
    buf[num] = str[idx];
    *ip_end = str + idx +1;
    ret = 1;
    } else {
    ret = 0;
    break;
    }
    num++;
    } else if (str[idx] == '.') {
    if (strlen(buf) == 0) {
    ret = 0;
    break;
    }

    ip_num[ip_idx] = atoi(buf);
    if (ip_num[ip_idx] <= 255) {
    ip_idx++;
    num = 0;
    memset(buf, 0, sizeof(buf));
    if (ip_idx == 4) {
    ret = 1;
    break;
    }
    } else {
    ret=0;
    break;
    }
    } else {
    break;
    }
    }

    if (ip_idx == 3) {
    if (ret == 1) {
    if (strlen(buf)==0) {
    ret=0;
    } else {
    ip_num[3] = atoi(buf);
    if (ip_num[3] <= 255) {
    ret = 1;
    } else {
    ret = 0;
    }
    }
    }
    } else {
    if (ip_idx != 4) {
    ret=0;
    }
    }

    if (ret == 1) {
    break;
    } else {
    continue;
    }
    }

    if (ret == 1) {
    sprintf(ip, "%u.%u.%u.%u", ip_num[0], ip_num[1], ip_num[2], ip_num[3]);
    }

    return ret;
    }

    unsigned int get_ip_city_string(char* ip) {
    FILE* wry_file = NULL;
    int idx = 0;
    char country[1024] = {"\0"};
    char area[1024] = {"\0"};

    if (NULL == ip || strlen(ip) == 0) {
    return 0;
    }

    for (idx = 0; idx < 2; ++idx) {
    if (idx == 0) {
    wry_file = fopen(NALI_QQWRY_PATH, "r");
    } else if (idx == 1) {
    wry_file=fopen("./QQWry.Dat","r");
    }
    if (wry_file!=NULL) {
    break;
    }
    }
    qqwry_get_location(country, area, ip, wry_file);
    fclose(wry_file);
    if (0 < strlen(country)) {
    printf(" %s",country);
    }
    if (0 < strlen(area)) {
    if (0 < strlen(country)) {
    printf(" ");
    }
    if (strlen(country) <= 0) {
    printf("unknown");
    } else {
    printf("%s",area);
    }
    }
    //printf("\n");
    return 0;
    }

     
  • 相关阅读:
    ARC 没有自动释放内存
    查看python的路径
    django 一些库
    实现点击按钮,出现隐藏布局
    蓝牙的开启以及搜索
    退出当前程序(应用)的小提示
    删除SharedPreferences的存储记忆
    BaseAdapter和SimpleAdapter的区别
    数据类型
    交互与注释
  • 原文地址:https://www.cnblogs.com/menggucaoyuan/p/2789805.html
Copyright © 2020-2023  润新知