socket实现tracert命令(控制台)

网络诊断三剑客:ping、telnet、tracert实战指南 网络诊断是分布式系统和微服务架构中的基础技能,其核心原理基于ICMP协议和TCP/IP协议栈。通过ICMP协议的Echo Request/Reply机制,ping命令可以检测网络连通性和延迟;telnet基于TCP三次握手实现端口可用性测试;tracert则利用TTL递减机制追踪网络路径。这些工具在Java开发、云原生环境及容器化部署中具有重要价值,能快速定位网络分区、端口不通或路由异常等问题。实际应用中,结合Linux命令与Java网络编程(如InetAddress.isReachable()),可构建自 阅读详情
#include <winsock2.h>
#include <iostream>
#include <windows.h>
using namespace std;

#define DATA_SIZE 32			//icmp包数据大小
#define RECV_MAX_SZIE 1024		//接收的数据最大长度
#define IP_TTL 4				//optname
#define MAX_HOP 30				//最大跃点数
#pragma comment(lib, "ws2_32.lib")

typedef struct tag_icmphdr		//icmp头
{
	unsigned char	icmp_type;
	unsigned char	icmp_code;	
	unsigned short	icmp_checksum;
	unsigned short	icmp_id;
	unsigned short	icmp_sequence;
	unsigned long	icmp_timestamp;
} ICMPHDR, *PICMPHDR;

typedef struct tag_iphdr
{
	unsigned char	ip_verlen; 
	unsigned char	ip_tos; 
	unsigned short	ip_totallength; 
	unsigned short	ip_id; 
	unsigned short	ip_offset; 
	unsigned char	ip_ttl; 
	unsigned char	ip_protocol; 
	unsigned short	ip_checksum; 
	unsigned int	ip_srcaddr; 
	unsigned int	ip_destaddr; 
} IPHDR, *PIPHDR;

void FillIcmp(char *icmp)
{
	PICMPHDR p = (PICMPHDR)icmp;
	p->icmp_type = 8;
	p->icmp_code = 0;
	p->icmp_checksum = 0;
	p->icmp_id = (unsigned short)::GetCurrentProcessId();
	p->icmp_sequence = 0;
	p->icmp_timestamp = 0;
}

USHORT CheckSum(USHORT *buf,int size)
{
	USHORT cksum=0;
	while(size>1)
	{
		cksum+=*buf++;
		size-=sizeof(USHORT);
	}
	if(size)
		cksum+=*buf++;
	cksum=(cksum>>16)+(cksum&0xffff);
	cksum+=(cksum>>16);
	return (USHORT)(~cksum);
}

int g_size = sizeof(ICMPHDR)+DATA_SIZE;

int _tmain(int argc, _TCHAR* argv[])
{
	WORD version = MAKEWORD(2,2);
	WSADATA data;
	WSAStartup(version, &data);
	if (LOBYTE(data.wVersion) != 2 || HIBYTE(data.wVersion) != 2)
	{
		cout << "WSAStartup failed" << endl;
		WSACleanup();
		return 0;
	}

	char ip[20];
	cout << "tracert:";
	cin >> ip;

	cout << endl << "Tracing route to" << ip << "[" << ip << "]" << "with a maximum of 30 hops." << endl << endl;

	SOCKADDR_IN addr;															
	addr.sin_family = AF_INET;
	addr.sin_addr.S_un.S_addr = inet_addr(ip);
	addr.sin_port = htons(0);

	SOCKET sock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);						     //创建原始套接字

	int bOpt = 1;
	int outTime = 2000;
	int rst;

	rst = setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (char*)&outTime, sizeof(int));	//设置发送超时
	if (SOCKET_ERROR == rst)
	{
		cout << "setsockopt erro" << endl;
		closesocket(sock);
		WSACleanup();
		return -1;
	}

	rst = setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char*)&outTime, sizeof(int));	//设置接收超时
	if (SOCKET_ERROR == rst)
	{
		cout << "setsockopt erro" << endl;
		closesocket(sock);
		WSACleanup();
		return -1;
	}


	char *icmp = (char*)malloc(g_size);						//为icmp包申请内存
	memset(icmp, 0, g_size);								//内存空间置零
	FillIcmp(icmp);											//填充icmp包

	unsigned short sequence = 0;							//序列号
	int count = 4;											//发送请求次数
	char recvbuf[RECV_MAX_SZIE];							//接收buf
	SOCKADDR_IN addrfrom;									//接收地址
	int len = sizeof(SOCKADDR);								//地址大小	
	int ttl = 1;											//TTL
	int result;

	while (1)
	{
		result = setsockopt(sock, IPPROTO_IP, IP_TTL, (char*)&ttl, sizeof(int));
		if (SOCKET_ERROR == result)
		{
			cout << "setsockopt IP_TTL error" << endl;
			closesocket(sock);
			WSACleanup();
			return -1;
		}

		
		((PICMPHDR)icmp)->icmp_checksum = 0;
		((PICMPHDR)icmp)->icmp_checksum = CheckSum((USHORT*)icmp, g_size);

		int nTickPre = ::GetTickCount();
		result = sendto(sock, icmp, g_size, 0, (SOCKADDR*)&addr, sizeof(SOCKADDR));	//向目标主机发送icmp请求包
		if (SOCKET_ERROR == result)
		{
			if (WSAETIMEDOUT == WSAGetLastError())
			{
				cout << "time out" << endl;
				continue;
			}
			else
			{
				cout << "sendto error" << endl;
				closesocket(sock);
				WSACleanup();
				return -1;
			}
		}

		result = recvfrom(sock, recvbuf, RECV_MAX_SZIE, 0, (SOCKADDR*)&addrfrom, &len);	//接收路由器返回的“icmp超时”报文(ttl等于0)
		if (SOCKET_ERROR == result)
		{
			if (WSAETIMEDOUT == GetLastError())
			{
				cout << ttl << ":	"  << "*	"<< "time out" << endl;
				++ttl;
				continue;
			}
			else
			{
				cout << "recvform error" << endl;
				closesocket(sock);
				WSACleanup();
				return -1;
			}
		}

		int nTickNow = ::GetTickCount();
		int time = nTickNow - nTickPre;

		PIPHDR pip = (PIPHDR)recvbuf;
		char sip[20];
		in_addr srcaddr;
		srcaddr.S_un.S_addr = pip->ip_srcaddr;
		strcpy(sip, inet_ntoa(srcaddr));
		if (time == 0)
			cout << ttl << ":	"  <<  "<1ms	"<< sip << endl;
		else
			cout << ttl << ":	"  << time << "ms	"<< sip << endl;

		if (strcmp(ip, sip) == 0)
		{
			cout << "tracert complete" << endl;
			break;
		}

		++ttl;

		if (ttl > 30)
		{
			break;
		}
	}

	return 0;
}

Java开发者必备:网络诊断工具ping、telnet、tracert详解 网络诊断是软件开发中的基础技能,尤其对于Java开发者而言更为重要。ICMP协议和TCP协议构成了网络连通性检测的技术基础,通过ping命令可以验证主机间的物理连通性,telnet则用于测试端到端的服务可达性。这些工具在微服务架构、容器化部署等现代技术场景中具有重要价值,能有效诊断Docker容器网络隔离、Kubernetes服务通信等问题。掌握网络诊断三剑客ping、telnet和tracert,可以帮助开发者快速定位云服务器跨可用区延迟、安全组规则失效等典型网络故障,提升分布式系统调试效率。 阅读详情

相关推荐

利用原始套接字实现tracert路由追踪

在windows的命令行下,使用tracert 域名/IP地址 可以记录本机到目的主机所经过的路由器的IP地址。这个功能使用原始套接字也可以实现。 我们通过不断地向目的主机发送ICMP-ECHORequest包,并且将包的TTL一开始设为1,这样一到达网关路由器后,路由器就检测到这个包超时了(TTL=0了),于是就会丢弃次包,并返回一个ICMP超时报文,在ICMP超时报文中,包含了路由器的IP地

ChenYitian 3727

socket编程总结

socket编程总结 主机字节序和网络字节序           字节序分为大端字节序(big endian)和小端字节序(little endian)               大端字节序:一个整数的高位存在内存的底地址,低位存在内存高地址              小端字节序:一个整数的高位存在内存的高地址,低位存在内存的低地址     现代PC大多采用小端字节序,所以小端字节序又

qi_700的博客 1346

自己实现的tracert命令,非常有用

自己实现的tracert命令 TRACEROTE 命令 MFC socket

C语言tracert源码,TraceRoute(tracert)源码(基于原始套接字实现)

//TraceRoute.h#ifndef_ITRACERT_H_#define_ITRACERT_H_#pragmapack(1)//IP数据报头typedefstruct{unsignedcharhdr_len:4;//lengthoftheheaderunsignedcharversion:4;//versionofIPunsignedchartos;//type...

weixin_39915171的博客 1351

linux下用socket+Qt实现的TraceRoute程序

本功能是通过linux下的socket实现网络TranceRoute功能,界面是用Qt完成的,帧长可设置,探索次数也可以设置,很适合新手的入门教程,代码有详细的注释!

用c实现tracert

用c实现tracert

一文搞懂tracert在windows和linux上的使用方法

最全的Linux教程,Linux从入门到精通。

m0_60721860的博客 3772

tracert 实现 C语言

tracert 实现 用C语言实现 类似于 命令行下的tracert命令

Socket API实现Trace Route

Windows自带的Tracert是向远程主机发送ICMP包进行追踪,但是目前很多主机关闭了ICMP答复,这个工具不太好使了~~~~~原理咱知道,正规的Trace不就是发送TTL依次递增的UDP包吗?什么网关和路由敢随意丢弃我们的UDP包而不通知我们?俺的ICMP包你可以不理,但是UDP包~~~~~不怕俺黑你???unit YRecords;interfaceuses  Windows;const

flyinwuhan的专栏 2095

tracert程序的实现过程并流输出

控制台程序来实现tracert命令,同时返回结果,存到缓冲中。算得上是的fks的肌肤上课的房间克水煎服思考几分啊上力困筋乏

利用socket编程实现traceroute功能

实现具有traceroute功能,跟踪IP地址,可以观察程序的实现情况。

php tracert,使用tracert查看网络状况

TRACERT是一种TCP/IP实用工具(源于“Trace Route”),在DOS和UNIX系统下都有此命令。它将您的计算机与目标服务器间传输一个包的路径情况报告给您。其最简单的使用方法为“TRACERT地址”,地址为目标服务器的域名或IP地址。(与PING命令类似,在DOS提示符下键入“TRACERT”并按回车键,可查看此命令的选项开关和参数使用方法)。您可看到如下类似结果:C:>tra...

weixin_34832150的博客 487

Label Studio保姆级教程:从零搭建医疗影像标注平台(DICOM格式支持)

本文提供基于Label Studio从零搭建医疗影像标注平台的保姆级教程。针对DICOM格式支持,详细阐述了环境部署、DICOM深度集成与预处理、团队协作权限管理以及质量审核闭环等核心环节,旨在构建一个高效、可落地的医疗AI数据标注解决方案,助力模型落地。

nft7creator的博客 305

linux 命令:ping、fping、gping、hping3、nping、tracert、traceroute、ip 和 ifconfig

linux 命令:ping、fping、gping、hping3、nping、tracert、traceroute

freeking101的博客 9万+

基于 Node.js + MongoDB 技术栈的小众开源短链接程序 —— Lynx

开源的短链接程序有很多,像 YOURLS、Shlink 等大多采用 PHP + MySQL 技术栈。但我之前的服务器配置一般,再加上自己写的小玩具使用的是 Node.js + MongoDB,这些环境已经装在服务器上了,因此更倾向于寻找一款同样基于这套技术栈的短链接程序。搜索了很久才找到这么一款基于的短链接程序——Lynx。这个开源项目非常小众,Star 数只有两百多。

zc_mk的博客 827

使用VIVADO 2019.1 搭建以太网接口

以太网 MAC+SGMII->GMII接口转换 以FPGA V7为例,搭建一个千兆以太网接口。运行环境为Vivado2019.1。板卡的FPGA V7与千兆网口芯片采用SGMII互联,最终实现FPGA与上位机之间的千兆网卡通信,实际实现时,V7采用MAC + GMII ->SGMII的结构。SGMII接口使用1G/2.5G Ethernet PCS/PMA or SGMII ip核,MAC层使用Tri Mode Ethernet MAC ip核。 由于MAC层IP不支持SGMII接口,因此需要G

qq_44641513的博客 8415

Visual C# Simulate "Tracert" Command

using System ; using System.Drawing ; using System.Collections ; using System.ComponentModel ; using System.Windows.Forms ; using Syste

1171

LinuxCNC开发实战:从安装到EtherCAT配置全解析

本文详细解析LinuxCNC开发实战,从系统安装到EtherCAT总线配置全流程。涵盖实时内核优化、伺服驱动器PDO映射、HAL配置及自定义运动学开发,帮助开发者快速搭建工业级数控系统,提升运动控制精度与稳定性。

rgv234567的博客 354

url访问 路由跟踪 命令 tracert

路由跟踪命令:用于确定 IP数据包访问目标所采取的路径,归属网络协议层 可用于对ping命令的补充,当无法ping通时,可用路由跟踪命令检测具体原因。win:tracert 的作用:从你的电脑到你的网站,中间经过了多少个网络节点。换句话说,从A这里到B家需要走多少条街~进而可以知道到底是哪条路出了问题。//命令格式: tracert [-d] [-h maximum_hops] [-j compu

wml 8938

Honeywell EPKS 核心功能块组态与执行调度实战解析

本文深入解析Honeywell EPKS系统的核心功能块组态与执行调度技术,涵盖控制模块(CM)、顺序控制模块(SCM)和输入输出模块(IOM)的配置方法。通过实战案例分享执行顺序(ORDERINCM)和CEE执行周期的优化策略,帮助工程师提升工业自动化系统的控制精度和运行效率。

weixin_28724319的博客 414

西电微原课设——矩阵式键盘数字密码锁设计

内容要求:根据设定好的密码,采用4x4矩阵键盘实现密码的输入功能。当密码输入正确之后,锁就打开(绿灯亮),10秒之后,锁自动关闭(红灯亮);如果连续输入三次密码不正确,就锁定按键5秒钟,同时发出报警(黄灯闪),5秒后,解除按键锁定,恢复密码输入。...

Polaris的博客 1万+

MTK socket 小结 4

昨天说了下socket基本几个函数,还有常用的是域名解析函数。 // 通过域名获得ip地址 // is_blocking,是否阻塞,现在只支持none block,也最好用none block // mod_id 如果没有立即获得,那么当查询成完毕,将向该mod 发送消息 // request_id 区分不同的DNS 查询结果。比如在同时查询两个以上,在返回的消息中,就可以通过id来进行区分,这个结果是哪一个查询结果 // addr 如果直接查询到结果,比如命中cache,那么

懒人 6785

【AFAC2026金融智能-赛题二】2亿像素的面条图,我切了1000刀拼回完美Markdown

摘要: AFAC2026金融智能创新大赛的「复杂金融文档还原挑战」任务是将高分辨率金融文档截图转换为结构化Markdown文本。面对2亿像素的“面条图”和严格的计算限制(禁用主流大模型,仅允许调用FinixDoc-VL API且模型需小于10M),作者提出四层流水线解决方案: 图像预处理:通过文本行投影检测在行间隙处智能切图,避免截断文字; API调度:5路并发轮询请求,结合内容哈希缓存与指数退避重试机制优化调用效率; 后处理:采用最长公共子串匹配去除文本重叠,并设计表格对齐算法修复跨块表格; 结果输出:按

171

tracert和traceroute介绍

一、tracert和traceroute简介 相同点:都是用来跟踪路由,帮助排查问题,关注的是过程,而ping关注的是结果 不同点:tracert请求是icmp echo报文     traceroute请求是UDP的报文,目标端口是30000以上随机端口 二、tracert使用到三种报文 icmp echo request #icmp Type0,客户端...

weixin_30721899的博客 623

程序员应用AI大模型创业实现财务自由的100种赚钱方案原理与实战指南

成功的 AI 创业者都遵循着 “技术 + 需求 + 变现” 的铁三角法则。记住:不是要做 “全能大模型”,而是成为某个垂直领域的 “AI 解决方案专家”。现在就开始行动:用周末 2 小时完成第一个 MVP,下周启动种子用户测试,三个月内找到可复制的盈利模式。当你实现第一个 10 万用户时,会发现财务自由的密码藏在持续迭代的每个 0.1 版本更新中。延伸思考:你的技术背景适合切入哪个细分领域?

AI天才研究院 1381

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

上一篇: setsockopt参数详解
下一篇: STL中map的数据结构
CButtonST
博客等级 码龄16年 42粉丝 15原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值