公司老大今天使用了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;
}
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
