ping实验报告
- 格式:docx
- 大小:97.37 KB
- 文档页数:14
常用网络命令实验报告常用网络命令实验报告概述:网络命令是计算机网络中常用的一种工具,可以用于网络故障排查、网络配置和网络性能监测等方面。
本实验旨在通过实际操作,深入了解并掌握常用网络命令的使用方法和功能。
一、Ping命令:Ping命令是网络中最常用的命令之一,用于测试与目标主机之间的连通性。
通过向目标主机发送ICMP Echo请求,并等待目标主机的响应,可以判断网络是否通畅。
在实验中,我们使用Ping命令测试了目标主机的连通性,并观察到了Ping命令的输出结果。
二、Tracert命令:Tracert命令用于跟踪数据包在网络中的路径,可以帮助我们了解数据包在经过的每个路由器上的延迟情况。
在实验中,我们使用Tracert命令追踪了数据包的路径,并观察到了每个路由器的IP地址和延迟时间。
三、Ipconfig命令:Ipconfig命令用于查看和配置网络接口的IP地址、子网掩码、默认网关等信息。
在实验中,我们使用Ipconfig命令查看了本机的IP地址,并通过修改网络设置,成功配置了新的IP地址。
四、Netstat命令:Netstat命令用于显示网络连接、路由表和网络接口统计信息。
在实验中,我们使用Netstat命令查看了当前主机的网络连接状态,并观察到了与目标主机的连接信息。
五、Nslookup命令:Nslookup命令用于查询域名的IP地址和反向解析,可以帮助我们了解域名和IP地址之间的映射关系。
在实验中,我们使用Nslookup命令查询了一个域名的IP地址,并观察到了查询结果。
六、Telnet命令:Telnet命令用于远程登录到目标主机,并通过命令行界面进行操作。
在实验中,我们使用Telnet命令成功登录到目标主机,并执行了一些简单的命令。
七、Curl命令:Curl命令是一个功能强大的网络工具,可以用于发送HTTP请求、下载文件等。
在实验中,我们使用Curl命令发送了一个HTTP请求,并成功获取了服务器返回的响应。
〖实验项目名称〗:计算机网络基础〖实验目的〗:1、熟悉网卡、掌握如何在Windows下如何察看网卡的型号、MAC地址、IP地址等参数。
2、熟悉Windows中的网络组建及各参数的设置和基本意义。
3、网络测试命令PING的用法。
〖实验任务与要求〗:1、网卡是网络中不可缺少的网络设备,掌握其使用情况,及如何设置其参数对网络的正常使用非常重要。
本部分要完成以下任务:(1)利用Windows下ipconfig 命令查看网卡的基本参数。
(2)如何设置网卡的IP地址。
2、Ping是个使用频率极高的实用程序,用于确定本地主机是否能与另一台主机交换(发送与接收)数据报。
根据返回的信息,就可以推断TCP/IP参数是否设置得正确以及运行是否正常。
(1)Ping 本机IP(Ping 本机机器名;Ping 127.0.0.1)。
(2)Ping 邻近计算机的IP(或者是对方计算机的机器名)。
(3)Ping 网站(前题是能接入Internet)。
〖实验过程〗:(实验步骤、记录、数据、分析)1.Ipconfig的使用(1)、开始-运行,在弹出的对框框中,输入CMD将进入黑白屏幕的DOS界面。
(2)、在“命令提示符”下输入ipconfig/all查看本机网卡的基本参数。
(2)利用“网上邻居”修改网络参数。
(3)PING命令的使用ping 127.0.0.1ping 本机IPping localhostping 局域网内其他IP PING命令参数:-n:发送count指定的ECHO数据包数,通过这个命令可以自己定义发送的个数,对衡量网络速度很有帮助。
能够测试发送数据包的返回平均时间,及时间的快慢程度。
默认值为 4。
-r:在“记录路由”字段中记录传出和返回数据包的路由。
通常情况下,发送的数据包是通过一系列路由才到达目标地址的,通过此参数可以设定,想探测经过路由的个数。
限定能跟踪到9个路由。
一般情况下,通过ping目标地址,可让对方返回TTL值的大小,通过TTL值可以粗略判断目标主机的系统类型是Windows还是UNIX/Linux,一般情况下Windows系统返回的TTL值在100-130之间,而UNIX/Linux系统返回的TTL值在240-255之间。
常见网络命令的使用实验报告一、实验目的了解和掌握常见网络命令的功能和使用方法,能够运用这些命令进行网络配置、故障排查和性能监测,提高对网络的管理和维护能力。
二、实验环境操作系统:Windows 10网络环境:连接到本地局域网和互联网三、实验内容及步骤(一)Ping 命令1、功能Ping 命令用于测试网络连接的可达性,通过向目标主机发送 ICMP (Internet Control Message Protocol,网际控制报文协议)回显请求数据包,并接收回显应答数据包来判断目标主机是否可达,以及网络延迟情况。
2、使用方法在命令提示符中输入“ping 目标主机的 IP 地址或域名”,例如“ping ”。
3、实验结果及分析执行 Ping 命令后,会显示一系列的统计信息,包括发送的数据包数量、接收的数据包数量、丢失的数据包数量以及往返时间的平均值、最小值和最大值。
如果所有数据包都成功接收,且往返时间较短,说明网络连接良好;如果有数据包丢失或往返时间较长,则可能存在网络延迟或丢包问题。
(二)Tracert 命令1、功能Tracert 命令用于跟踪数据包从本地主机到目标主机所经过的路径,并显示每个中间节点的 IP 地址和往返时间。
2、使用方法在命令提示符中输入“tracert 目标主机的 IP 地址或域名”,例如“tracert ”。
3、实验结果及分析执行 Tracert 命令后,会逐行显示数据包经过的每个路由器的 IP 地址和往返时间。
通过分析这些信息,可以确定网络中的故障点或延迟较大的节点,有助于排查网络连接问题。
(三)Ipconfig 命令1、功能Ipconfig 命令用于显示本地网络连接的配置信息,包括 IP 地址、子网掩码、默认网关等。
2、使用方法在命令提示符中输入“ipconfig”可显示基本信息,输入“ipconfig /all”可显示更详细的信息。
3、实验结果及分析通过查看 Ipconfig 命令的输出结果,可以了解本地网络连接的配置情况。
计算机网络实验报告专业:计算机科学与技术系(班):计算机17-6姓名:魏士博(5011213617)课程名称:计算机网络实验项目:实验一常用网络命令指导老师:邬欢欢1、实验目的(1)掌握常用网络命令的使用方法;(2)熟悉和掌握网络管理、网络维护的基本内容和方法2、实验内容Windows环境下常用的网络命令的使用。
1.Ping 命令(1)Ping命令的格式如下:ping [-t] [-a] [-n count] [-l length] [-f] [-i ttl] [-v tos] [-r count] [-s count] [[-j computer-list] | [-k computer-list]] [-w timeout] destination-list(2)通常用ping命令来测试某两台计算机之间是否连通:(3)利用ping命令测试网络状况的主要步骤如下:2.ipconfig命令该命令显示所有当前的 TCP/IP 网络配置值。
ipconfig命令格式如下:ipconfig [/? | /all | /release [adapter] | /renew [adapter]3.Arp命令该命令显示和修改“地址解析协议 (ARP)”缓存中的项目。
ARP 缓存中包含一个或多个表,它们用于存储 IP 地址及其经过解析的以太网或令牌环物理地址。
计算机上安装的每一个以太网或令牌环网络适配器都有自己单独的表。
如果在没有参数的情况下使用,则 arp 命令将显示帮助信息。
该命令格式如下:arp[-a [InetAddr] [-N IfaceAddr]] [-g [InetAddr] [-N IfaceAddr]] [-d InetAddr [IfaceAddr]] [-s InetAddr EtherAddr [IfaceAddr]]Net命令许多 Windows 2000 网络命令都以词 net 开头。
实验报告
实验步骤:
一、
1、关闭windows防火墙。
2、利用ping命令向几个站点发送信息,例如:“ping
192.168.31.127”。
3、使用命令提示符arp /a 显示ARP表项、出现结果即所有曾
有过联系的主机都会有显示。
二、使用命令提示符arp /d 删除记录,再次显示表项(arp /a),则arp
/a命令后,输出的结果为“No ARP Entries found”。
如图:
三、使用ping命令执行ping 出现
由于在机房ping 时出现的IP地址为61.135.169.125
所以,现在直接ping IP地址出现的结果为
使用arp /s将百度IP改错,则无法打开百度网页。
改回来后又可以重新登录百度网页。
四、利用arp /s命令增加一条错误的IP地址与MAC地址映射信息,再通
过ping命令判断该计算机是否能够正常发送信息。
PING实验报告沈阳工程学院学生实验报告实验室名称:信息工程系软件实验室实验课程名称:计算机网络实验项目名称:icmp协议应用——ping解析班级:姓名:学号:实验日期:2012年04月28日实验台编号:23 指导教师:批阅教师(签字):成绩:篇二:网络编程实验_ping实验报告网络编程-ping程序设计实验指导书一.实验目的(1)熟悉原始套接字编程。
(2)了解网络的结构。
(3)了解网络传输底层协议。
二.实验要求ping程序是用于测试网络连通性的程序。
要求在windows环境下实现基本的ping程序功能.在命令提示符下输入:ping ***.***.***.*** 其中***为目的主机的ip地址,不要求支持域名,对是否带有开关变量也不做要求。
不带开关变量时,要求返回4次响应。
返回信息的格式:reply from ***.***.***.*** 或request timeout (无法ping通的情况)三.实验原理1、ping的工作原理ping 程序是用来探测主机到主机之间是否可通信,如果不能ping 到某台主机,表明不能和这台主机建立连接。
ping 使用的是icmp协议,它发送icmp 回送请求消息给目的主机。
icmp协议规定:目的主机必须返回icmp回送应答消息给源主机。
如果源主机在一定时间内收到应答,则认为主机可达。
icmp协议通过ip协议发送的,ip协议是一种无连接的,不可靠的数据包协议。
因此,保证数据送达的工作应该由其他的模块来完成。
其中一个重要的模块就是icmp(网络控制报文)协议。
当传送ip数据包发生错误--比如主机不可达,路由不可达等等,icmp协议将会把错误信息封包,然后传送回给主机。
给主机一个处理错误的机会,这也就是为什么说建立在ip层以上的协议是可能做到安全的原因。
icmp数据包由8bit的错误类型和8bit的代码和16bit的校验和组成。
而前 16bit 就组成了icmp所要传递的信息。
电子科技大学实验报告学生姓名:学号:指导教师:日期:年月日实验项目名称:报告评分:教师签字:一、实验原理“PING”这个名字源于声纳定位操作。
PING程序的目的是测试另一台主机是否可达,它发送ICMP回送请求报文给被测主机,并等待返回的ICMP回送应答或差错报告报文。
ICMP协议(RFC 792)是IP协议的辅助协议,提供差错报告和查询机制。
一台主机的可达性不仅取决于IP层是否可达,还取决于使用的高层协议及端口号。
仅当被测主机可达时,PING程序才能收到返回的ICMP回送应答报文,并能测出到该主机的往返时间。
如果被测主机不可达,PING程序会收到一些ICMP差错报告报文,甚至收不到任何返回信息。
根据ICMP差错报告报文的类型可粗略判定主机不可达的原因。
不同的物理网络具有不同的最大传送单元(MTU)值,因此可能需要对IP分组进行分片操作使其能够通过这些物理网络。
当IP分组被分片时,需要修改分组头中的标志、分片偏移和总长度值,其余各字段将被复制到所有分片中。
已经分片的IP分组在遇到具有更小MTU的网络时还会被再次分片。
TTL字段是由发送端初始设置在IP分组首部中的一个8 bit字段,不同操作系统上的不同应用程序指定的TTL初始值不同。
路由器在转发每个IP分组时需要将该分组的TTL值减1或减去该分组在路由器中停留的秒数。
由于大多数路由器转发IP分组的时延都小于1秒钟,因此TTL最终成为一个跳站计数器,即分组每经过一台路由器其TTL值被减1。
TTL字段的目的是为了防止分组在选路时被无休止的转发。
当路由器收到一份需转发的IP分组时,如果该分组的TTL值为1,路由器则丢弃该分组,并向分组源发送一份ICMP的TTL超时报文。
TRACE程序使用IP分组首部的TTL字段(生存时间)和ICMP报文,让使用者可以看到IP分组从一台主机传到另一台主机所经过的路由。
TRACE程序首先发送一份TTL值为1的IP分组给目的主机,处理该IP分组的第1个路由器即会返回一份以自己的IP地址为源的携带有ICMP超时报文的IP分组,这样TRACE程序就得到了该路径中第1个路由器的IP地址。
遵义师范学院计算机和信息科学学院实验报告(2012—2013学年第一学期)课程名称:网络安全实验班级:计科一班学号:10410901036姓名:陈志军任课教师:蒲晓川计算机和信息科学学院《网络安全扫描》实验报告实验名称实验6-1 Ping主机扫描实验指导教师蒲晓川网络安全防实验类型实验学时 2 实验时间11.29范一、实验目的和要求1.了解和学习Ping命令扫描实现的基本原理。
2.学习和掌握Windows Ping命令的操作使用及其在主机扫描中的使用。
3.学习和掌握Ping扫描子网主机。
二、实验仪器和器材计算机一台Vmware虚拟机三、实验内容及步骤1、Windows Ping命令重要参数使用。
(1)设置发送Ping 探测报文的数量,发送ICMP报文数据包,检测当前网络状况,如图1.1所示:(2)连续发送ICMP探测报文1、通过使用“-t”参数实现连续发送ICMP探测报文。
如图1.2所示:图1.2 连续发送ICMP探测报文2、使用Ctrl+Break命令,查看ping统计信息。
如图1.3所示:图1.3 用Ctrl+Break命令查看ping统计信息3、使用Ctrl+C命令,可以结束发送ICMP Echo Request报文。
如图1.4所示:(3)配置Ping探测报文的TTL值,发送TTL值为1的ICMP报文。
如图1.5所示:(4)配置Ping探测报文大小。
如图1.6所示:(5)禁止对Ping探测报文分片。
如图1.7所示:(6)设置Ping命令的请求超时时间。
Ping命令的默认回应时间是1000毫秒,用“-w 时间值”参数可以修改回应时间。
如图1.8所示:图1.8设置Ping命令的超时等待时间2、利用Ping命令进行主机扫描(1)扫描内部实验网的目标主机。
如图2.1所示:图2.1 Ping目标主机扫描结果(2)、Ping外网测试。
如图2.2所示:图2.2 Ping师院教务处网站、(3)、Ping域名。
大学生ping命令实验心得一、实验目的1.掌握ping命令的基本用法,了解ping命令的原理。
2.学会使用ping命令进行网络故障排查和网络性能测试。
3.提高自己的网络编程能力,为以后的学习和工作打下基础。
二、实验内容1.ping命令的基本用法2.ping命令的原理3.ping命令的高级用法4.ping命令在网络故障排查和网络性能测试中的应用三、实验步骤1.ping命令的基本用法(1)查询本机IP地址在Windows系统中,打开命令提示符,输入“ipconfig”命令,回车,即可查看本机IP地址。
在Linux系统中,打开终端,输入“ifconfig”或“ipaddr”命令,回车,即可查看本机IP地址。
(2)查询目标主机IP地址在Windows系统中,打开命令提示符,输入“ping目标主机名”或“ping目标主机IP地址”,回车,即可查看目标主机IP地址。
在Linux系统中,打开终端,输入“ping目标主机名”或“ping目标主机IP地址”,回车,即可查看目标主机IP地址。
(3)测试网络连通性在Windows系统中,打开命令提示符,输入“ping目标主机名”或“ping目标主机IP地址”,回车,即可测试网络连通性。
在Linux系统中,打开终端,输入“ping目标主机名”或“ping目标主机IP地址”,回车,即可测试网络连通性。
2.ping命令的原理ping命令是网络诊断中最常用的一个工具,它通过发送ICMP报文并接收ICMP报文来检测网络的连通性。
当ping 命令发送一个ICMP报文给目标主机时,如果目标主机能够正常响应,说明网络是连通的;如果目标主机无法响应或者响应超时,说明网络可能存在问题。
ICMP(InternetControlMessageProtocol)是一种网络层协议,用于在IP主机、路由器之间传递控制消息。
ICMP报文可以分为两种类型:差错报告报文和查询报文。
其中,差错报告报文主要用于报告网络中的错误情况,如目的不可达、超时等;查询报文主要用于获取网络中的一些信息,如目的主机是否可达、路由是否通畅等。
一.实验目的PING程序是我们使用的比较多的用于测试网络连通性的程序。
PING程序基于ICMP,使用ICMP的回送请求和回送应答来工作。
由计算机网络课程知道,ICMP是基于IP的一个协议,ICMP包通过IP的封装之后传递。
课程设计中选取PING程序的设计,其目的是希望同学们通过PING程序的设计,能初步掌握TCP/IP网络协议的基本实现方法,对网络的实现机制有进一步的认识。
二.实验内容和要求1、RAW模式的SOCKET编程PING程序是面向用户的应用程序,该程序使用ICMP的封装机制,通过IP 协议来工作。
为了实现直接对IP和ICMP包进行操作,实验中使用RAW模式的SOCKET编程。
熟悉SOCKET的编程,包括基本的系统调用如SOCKET、BIND等;2.具体内容2.1定义数据结构需要定义好IP数据报、ICMP包等相关的数据结构;2.2程序实现在WINDOWS环境下实现PING程序;2.3程序要求在命令提示符下输入:PING ΧΧΧ.ΧΧΧ.ΧΧΧ.ΧΧΧ其中ΧΧΧ为目的主机的IP地址,不要求支持域名,对是否带有开关变量也不做要求。
不带开关变量时,要求返回4次响应。
返回信息的格式:REPLY FROM ΧΧΧ.ΧΧΧ.ΧΧΧ.ΧΧΧ或REQUEST TimeOut (无法PING通的情况)。
三.基本思路及所涉及的相关理论3.1 功能模块设计本系统共有 4 个模块,分别是初始化模块、功能控制模块、数据控制模块、数据报解读模块和ping测试模块.3.1.1 初始化模块。
改模块用于初始化各个全局变量,为全局变量赋初始值;初始化,加载库。
3.1.2功能控制模块。
改模块是被其它模块调用,其功能包括获取参数、计算校验和填充数据报文、释放占用资源和显示用户帮助。
3.1.3数据报解读模块。
改模块用于解读接收到的报文和选项。
3.1.4测试模块。
改模块是本程序的核心模块,调用其他模块实现其功能,主要是实现的功能。
3.2系统流程图系统执行的流程图2.2所示。
程序首先调用IniPing()函数初始化各全局变量,然后GetArgments()函数获取用户输入的参数,检查用户输入的参数,如果参数不正确或者没有输入参数,则显示用户帮助信息(User help ),并结束程序;如果参数正确,则对指定目的地执行Ping命令,如果Ping通,则显示Ping结果并释放占用资源,如果没有Ping通,则报告错误信息,并释放占用资源。
图2.2 系统流程图3.3参数获取(GetArgments()函数)流程获取的参数包括“-r”(记录路由)、“-n”(记录条数程序,任意的整数)和datasize(数据报大小)。
程序首先判断每一个参数的第一字符,如果第一个字符是“-”(短横线),则认为是“-r”或者“-n”中的一个,然后作进一步判断。
如果该参数的第二个字符是数字,则判断该参数为记录的条数,如果该参数的第二个字符是“r”,则判断该参数为“-r”,用于记录路由;如果参数的第一个字符是数字,则认为参数是IP地址;或者datasize,然后作进一步的判断。
如果该参数中不存在非数字的字符,则判断该参数为datasize;如果存在非数字的字符,则判断该参数为IP地址;其他情况则判断为主机名。
3.4ping()函数流程ping()函数是本程序的核心部分它调用其他模块的函数来实现,其主要步骤包括创建接字,设置路由选项(如果需要的话)、设置接收和发送超时值、名字解析(如果需要的话)、分配内存、创建ICMP报文、发送ICMP请求报文、接收ICMP应答报文和解读ICMP报文。
四.数据结构设计本程序定义了3个结构体:-iphdr、-icmphdr、和-ipotionhdr,分别用于存放IP报头信息、ICM P报头信息和IP路由选项信息。
4.1定义IP报头结构体Typedef struct _iphdr{Unsigned int h_len:4;Unsigned int version:4;Unsigned char tos;Unsigned short total_len;Unsigned short ident;Unsigned short frag_flags;Unsigned char ttl;Unsigned chor proto;Unsigned short checksum;Unsigned int sourceIP;Unsigned int destIP;} IpHeader;其中各字段表示意义如下。
h-len:4 : 表示IP报头长度,首部长度指的是首部占32bit字的数目,包括任何选项。
由于它是一个4bit 字段,因此首部最长为60个字节,不包括任何选项的IP报头是20个字节。
Version:4: 表示IP的版本号,这里表示Ipv4.。
Top: 表示服务的类型,最小时延,最大吞吐量,最高可靠性和最小费用。
Total –len: 整个IP数据报的总长度。
Ident: 唯一的标识符,标识主机发送的每一份数据报。
Frag-flags: 分段标志,表示过长的数据报是否要分段。
Ttl: 生存期,表示数据报可以经过的最多路由器数。
Proto: 协议类型(TCP、UDP等)。
Checksum: 校验和。
sourceIP: 源IP地址。
destIP: 目的IP地址。
4.2定义ICMP报头结构体Typedef struct –icmphdr{BYTE i_type;BYTE i_code :USHORT i_cksum;USHORT i_id;USHORT i_seq;ULONG timestamp;} IcmpHeader;其中各字段表示意义如下。
I_tye : ICMP报文类型。
I_code : 该类型中的代码号,一种ICMP 报文的类型号和该类型中的代码号共同决定。
、I_cksum: 校验和。
I_seq: 序列号,序列号从0开始,每发送一次新的回显请求就加1. Timestamp: 时间。
4.3定义IP 选项结构体Typedef struct _ipoptionhdr{Unsigned char code;Unsigned char len;Unsigned char ptr;Unsigned loang addr[9];} IcmpHeader;其中各字段表示意义如下。
Code: 指明IP 选项类型,对于路由记录选项,它的值是7。
Len: 选项头长度。
Ptr: 地址指针字段,是一个基于1的指针,指向存放下一个IP地址的位置。
addr[9]: 记录的Ip地址列表,由于IP首部中选项的空间有限,所以可以记录的Ip地址最多是9个.五.各模块的代码5.1初始化模块void InitPing(){WSADATA wsaData;icmp_data = NULL;seq_no = 0;recvbuf = NULL;RecordFlag = FALSE;lpdest = NULL;datasize = DEF_PACKET_SIZE;PacketNum = 5;SucessFlag = FALSE;/*Winsock初始化*/if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0){/*如果初始化不成功则报错,GetLastError()返回发生的错误信息*/ printf("WSAStartup() failed: %d\n", GetLastError());return ;}m_socket = INVALID_SOCKET;}5.2功能控制模块/*显示信息函数*/void UserHelp(){printf("UserHelp: ping -r <host> [data size]\n");printf(" -r record route\n");printf(" -n record amount\n");printf(" host remote machine to ping\n");printf(" datasize can be up to 1KB\n");ExitProcess(-1);}/*获取ping选项函数*/void GetArgments(int argc,char** argv){int i;int j;int exp;int len;int m;/*如果没有指定目的地地址和任何选项*/if(argc == 1){printf("\nPlease specify the destination IP address and the ping option as follow!\n");UserHelp();}for(i = 1; i < argc; i++){len = strlen(argv[i]);if (argv[i][0] == '-'){/*选项指示要获取记录的条数*/if(isdigit(argv[i][1])){PacketNum = 0;for(j=len-1,exp=0;j>=1;j--,exp++)/*根据argv[i][j]中的ASCII值计算要获取的记录条数(十进制数)*/PacketNum += ((double)(argv[i][j]-48))*pow(10,exp);}else{switch (tolower(argv[i][1])){/*选项指示要获取路由信息*/case 'r':RecordFlag = TRUE;break;/*没有按要求提供选项*/default:UserHelp();break;}}}/*参数是数据报大小或者IP地址*/else if (isdigit(argv[i][0])){for(m=1;m<len;m++){if(!(isdigit(argv[i][m]))){/*是IP地址*/lpdest = argv[i];break;}/*是数据报大小*/else if(m==len-1)datasize = atoi(argv[i]);}}/*参数是主机名*/elselpdest = argv[i];}}/*求校验和函数*/USHORT CheckSum(USHORT *buffer, int size){unsigned long cksum=0;while (size > 1){cksum += *buffer++;size -= sizeof(USHORT);}if (size){cksum += *(UCHAR*)buffer;}/*对每个16bit进行二进制反码求和*/cksum = (cksum >> 16) + (cksum & 0xffff);cksum += (cksum >>16);return (USHORT)(~cksum);}/*填充ICMP数据报字段函数*/void FillICMPData(char *icmp_data, int datasize){IcmpHeader *icmp_hdr = NULL;char *datapart = NULL;icmp_hdr = (IcmpHeader*)icmp_data;/*ICMP报文类型设置为回显请求*/icmp_hdr->i_type = ICMP_ECHO;icmp_hdr->i_code = 0;/*获取当前进程IP作为标识符*/icmp_hdr->i_id = (USHORT)GetCurrentProcessId(); icmp_hdr->i_cksum = 0;icmp_hdr->i_seq = 0;datapart = icmp_data + sizeof(IcmpHeader);/*以数字0填充剩余空间*/memset(datapart,'0',datasize-sizeof(IcmpHeader));}/*释放资源函数*/void FreeRes(){/*关闭创建的套接字*/if (m_socket != INVALID_SOCKET)closesocket(m_socket);/*释放分配的内存*/HeapFree(GetProcessHeap(), 0, recvbuf);HeapFree(GetProcessHeap(), 0, icmp_data);/*注销WSAStartup()调用*/WSACleanup();return ;}5.3数据报解读模块/*解读IP选项头函数*/void DecodeIPOptions(char *buf, int bytes){IpOptionHeader *ipopt = NULL;IN_ADDR inaddr;int i;HOSTENT *host = NULL;/*获取路由信息的地址入口*/ipopt = (IpOptionHeader *)(buf + 20);printf("RR: ");for(i = 0; i < (ipopt->ptr / 4) - 1; i++){inaddr.S_un.S_addr = ipopt->addr[i];if (i != 0)printf(" ");/*根据IP地址获取主机名*/host = gethostbyaddr((char *)&inaddr.S_un.S_addr,sizeof(inaddr.S_un.S_addr), AF_INET);/*如果获取到了主机名,则输出主机名*/if (host)printf("(%-15s) %s\n", inet_ntoa(inaddr), host->h_name); /*否则输出IP地址*/elseprintf("(%-15s)\n", inet_ntoa(inaddr));}return;}/*解读ICMP报头函数*/void DecodeICMPHeader(char *buf, int bytes, SOCKADDR_IN *from){IpHeader *iphdr = NULL;IcmpHeader *icmphdr = NULL;unsigned short iphdrlen;DWORD tick;static int icmpcount = 0;iphdr = (IpHeader *)buf;/*计算IP报头的长度*/iphdrlen = iphdr->h_len * 4;tick = GetTickCount();/*如果IP报头的长度为最大长度(基本长度是20字节),则认为有IP选项,需要解读IP选项*/if ((iphdrlen == MAX_IP_HDR_SIZE) && (!icmpcount))/*解读IP选项,即路由信息*/DecodeIPOptions(buf, bytes);/*如果读取的数据太小*/if (bytes < iphdrlen + ICMP_MIN){printf("Too few bytes from %s\n",inet_ntoa(from->sin_addr));}icmphdr = (IcmpHeader*)(buf + iphdrlen);/*如果收到的不是回显应答报文则报错*/if (icmphdr->i_type != ICMP_ECHOREPLY){printf("nonecho type %d recvd\n", icmphdr->i_type);return;}/*核实收到的ID号和发送的是否一致*/if (icmphdr->i_id != (USHORT)GetCurrentProcessId()){printf("someone else's packet!\n");return ;}SucessFlag = TRUE;/*输出记录信息*/printf("%d bytes from %s:", bytes, inet_ntoa(from->sin_addr));printf(" icmp_seq = %d. ", icmphdr->i_seq);printf(" time: %d ms", tick - icmphdr->timestamp);printf("\n");icmpcount++;return;}4Ping 测试模块/*ping函数*/void PingTest(int timeout){int ret;int readNum;int fromlen;struct hostent *hp = NULL;/*创建原始套接字,该套接字用于ICMP协议*/m_socket = WSASocket(AF_INET, SOCK_RAW, IPPROTO_ICMP, NULL, 0,WSA_FLAG_OVERLAPPED);/*如果套接字创建不成功*/if (m_socket == INVALID_SOCKET){printf("WSASocket() failed: %d\n", WSAGetLastError());return ;}/*若要求记录路由选项*/if (RecordFlag){/*IP选项每个字段用0初始化*/ZeroMemory(&IpOption, sizeof(IpOption));/*为每个ICMP包设置路由选项*/IpOption.code = IP_RECORD_ROUTE;IpOption.ptr = 4;IpOption.len = 39;ret = setsockopt(m_socket, IPPROTO_IP, IP_OPTIONS,(char *)&IpOption, sizeof(IpOption));if (ret == SOCKET_ERROR){printf("setsockopt(IP_OPTIONS)failed: %d\n",WSAGetLastError());}}/*设置接收的超时值*/readNum = setsockopt(m_socket, SOL_SOCKET, SO_RCVTIMEO,(char*)&timeout, sizeof(timeout));if(readNum == SOCKET_ERROR){printf("setsockopt(SO_RCVTIMEO)failed: %d\n",WSAGetLastError());return ;}/*设置发送的超时值*/timeout = 1000;readNum = setsockopt(m_socket, SOL_SOCKET, SO_SNDTIMEO,(char*)&timeout, sizeof(timeout));if (readNum == SOCKET_ERROR){printf("setsockopt(SO_SNDTIMEO)failed: %d\n",WSAGetLastError());return ;}/*用0初始化目的地地址*/memset(&DestAddr, 0, sizeof(DestAddr));/*设置地址族,这里表示使用IP地址族*/DestAddr.sin_family = AF_INET;if ((DestAddr.sin_addr.s_addr = inet_addr(lpdest)) == INADDR_NONE) {/*名字解析,根据主机名获取IP地址*/if ((hp = gethostbyname(lpdest)) != NULL){/*将获取到的IP值赋给目的地地址中的相应字段*/memcpy(&(DestAddr.sin_addr), hp->h_addr, hp->h_length);/*将获取到的地址族值赋给目的地地址中的相应字段*/DestAddr.sin_family = hp->h_addrtype;printf("DestAddr.sin_addr = %s\n", inet_ntoa(DestAddr.sin_addr));}/*获取不成功*/else{printf("gethostbyname() failed: %d\n",WSAGetLastError()); return ;}}/*数据报文大小需要包含ICMP报头*/datasize += sizeof(IcmpHeader);/*根据默认堆句柄,从堆中分配MAX_PACKET内存块,新分配内存的内容将被初始化为0*/icmp_data =(char*) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,MAX_PACKET);recvbuf =(char*) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,MAX_PACKET);/*如果分配内存不成功*/if (!icmp_data){printf("HeapAlloc() failed: %d\n", GetLastError());return ;}/* 创建ICMP报文*/memset(icmp_data,0,MAX_PACKET);FillICMPData(icmp_data,datasize);while(1){static int nCount = 0;int writeNum;/*超过指定的记录条数则退出*/if (nCount++ == PacketNum)break;/*计算校验和前要把校验和字段设置为0*/((IcmpHeader*)icmp_data)->i_cksum = 0;/*获取操作系统启动到现在所经过的毫秒数,设置时间戳*/((IcmpHeader*)icmp_data)->timestamp = GetTickCount();/*设置序列号*/((IcmpHeader*)icmp_data)->i_seq = seq_no++;/*计算校验和*/((IcmpHeader*)icmp_data)->i_cksum = CheckSum((USHORT*)icmp_data, datasize);/*开始发送ICMP请求 */writeNum = sendto(m_socket, icmp_data, datasize, 0,(struct sockaddr*)&DestAddr, sizeof(DestAddr));/*如果发送不成功*/if (writeNum == SOCKET_ERROR){/*如果是由于超时不成功*/if (WSAGetLastError() == WSAETIMEDOUT){printf("timed out\n");continue;}/*其他发送不成功原因*/printf("sendto() failed: %d\n", WSAGetLastError());return ;}/*开始接收ICMP应答 */fromlen = sizeof(SourceAddr);readNum = recvfrom(m_socket, recvbuf, MAX_PACKET, 0,(struct sockaddr*)&SourceAddr, &fromlen);/*如果接收不成功*/if (readNum == SOCKET_ERROR){/*如果是由于超时不成功*/if (WSAGetLastError() == WSAETIMEDOUT){printf("timed out\n");continue;}/*其他接收不成功原因*/printf("recvfrom() failed: %d\n", WSAGetLastError());return ;}/*解读接收到的ICMP数据报*/DecodeICMPHeader(recvbuf, readNum, &SourceAddr);}}5.5主函数int main(int argc, char* argv[]){InitPing();GetArgments(argc, argv);PingTest(1000);/*延迟1秒*/Sleep(1000);if(SucessFlag)printf("\nPing end, you have got %.0f records!\n",PacketNum); elseprintf("Ping end, no record!");FreeRes();getchar();return 0;}六.心得和总结此次做的是win32控制台程序,按照书上和网上找的资料和教程,编译无误没有太大的问题,最后执行程序的时候要通过系统的cmd命令来运行,结果如下图:七.运行和调试:6.参考文献:《《Visual c++高级编程》》,张力,人民邮电出版社,2002年3月。