计算机网络实验之Ping程序设计实现分析

合集下载

计算机网络实验报告(Ping命令)

计算机网络实验报告(Ping命令)

〖实验项目名称〗:计算机网络基础〖实验目的〗: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之间。

Ping 程序设计原理(2023最新版)

Ping 程序设计原理(2023最新版)

Ping 程序设计原理⒈引言本文档旨在介绍 Ping 程序设计原理,包括其概述、设计原则和实现细节。

Ping 是一种网络工具,用于测试主机之间的网络连通性。

本文将讨论 Ping 的基本原理、实现方法以及使用示例。

⒉概述Ping 是一种基于 ICMP(Internet Control Message Protocol)的网络工具,它通过向目标主机发送 ICMP 回显请求消息(Echo Request)并等待目标主机的 ICMP 回显应答消息(Echo Reply)来测试主机之间的连通性。

⒊设计原则在设计 Ping 程序时,需要考虑以下原则:- 网络层协议:Ping 使用 ICMP 协议进行通信,所以需要对ICMP 协议进行理解和实现。

- 数据包处理:Ping 程序需要构造 ICMP 回显请求消息,并解析目标主机的 ICMP 回显应答消息。

- 超时机制:Ping 程序需要设置合理的超时时间,如果在超时时间内未接收到回显应答,则认为连接超时。

- 循环测试:Ping 程序可以通过循环发送 ICMP 回显请求消息来进行连通性测试。

⒋实现细节⑴ ICMP 协议ICMP 是一种网络层协议,用于在 IP 网络中传递错误消息和操作性消息。

在 Ping 程序中,我们使用 ICMP 协议来进行主机之间的连通性测试。

⑵构造 ICMP 回显请求消息Ping 程序在发送 ICMP 回显请求消息时,需要构造相应的数据包。

构造 ICMP 数据包过程需要设置以下字段:- 类型:设置为 8,表示 ICMP 回显请求消息。

- 代码:通常设为 0。

- 校验和:对 ICMP 数据包进行校验和计算。

- 标识符和序列号:用于识别 ICMP 回显请求消息和回显应答消息之间的对应关系。

- 数据:可以包含任意数据,用于传递给目标主机处理。

⑶解析 ICMP 回显应答消息Ping 程序在接收到目标主机的 ICMP 回显应答消息时,需要解析其内容。

解析 ICMP 数据包时,需要检查以下字段:- 类型:应为 0,表示 ICMP 回显应答消息。

计算机网络实验之Ping程序的设计与实现

计算机网络实验之Ping程序的设计与实现

课程名称计算机网络实验序号实验五实验项目 Ping程序的设计与实现2017年 03月 25 日实验报告要求1、实验报告封面填表说明(每份实验报告必须附上封面)(1)课程名称:要求与实验大纲和实验指导书中的课程名称一致。

(2)实验序号:指该课程的第几个实验。

(3)实验项目:要求与实验大纲和实验指导书中的实验项目一致。

(4)实验地点:填写完成该实验项目所在的实验室名称。

(5)实验学时:要求与实验大纲和实验指导书中完成该实验项目所需学时一致。

(6)实验类型:是指演示性、操作性、验证性、综合性、设计性。

演示性:教师操作,学生观察,验证理论、说明原理和方法。

操作性:学生按要求动手拆装、调试实验装置或上机操作,掌握其基本原理和方法。

验证性:按实验指导书(教材)要求,由学生通过操作验证所学理论,加深对理论、知识的理解,掌握基本实验知识、方法、技能、数据处理等。

综合性:实验内容涉及本课程的综合知识或相关课程的知识,运用多的知识、多种方法,按要求或自拟实验方案进行实验。

主要培养学生综合运用所学知识、实验方法和实验技能,以培养其分析、解决问题的能力。

设计性:给定实验目的、要求和实验条件,学生自己设计实验方案并加以实现的实验。

学生独立完成从查阅资料、拟定实验方案、实验方法和步骤(或系统分析和设计)、选择仪器设备(或自行设计缺制作)进行实验并完成实验全过程,形成实验报告,培养学生自主实验的能力。

2、实验报告的格式3、教师批改学生实验报告要求(1)批改:全部批改及更正错误。

(2)评分:按百分制评分,不能评分为“优、良、中、差”或“A、B、C”。

(3)签名及批改日期:任课教师必须在每份学生实验报告中签名和写上批改日期。

(4)成绩:填写学生实验成绩表,实验成绩作为考试成绩评定的依据。

(4)评语:任课教师批改学生实验报告时,应给出简明扼要的评语。

[计算机]ping实验报告

[计算机]ping实验报告
实验报告
学生__
学 号:
一、实验室名称:3302
二、实验项目名称:基于 ICMP 协议的 ping 程序
三、实验原理:
ping 程序使用 ICMP 协议实现。首先 Ping 向目标发送一个 ICMP 响应-请求(type=8),当目标主机 得到请求后,返回 ICMP 响应-应答,根据返回信息的不同判断目标主机是否存在。
七、实验结论:
.
八、总结与心得体会:
九、对本实验过程与字:
.
主机 A
向 192.168.3.1 发送响 应-请求包
主机存在
接收到应答 向发送响应-请求包
主机不存在
超时
主机 实际存在
主机 实际不存在
.
四、实验目的:
1)理解 ICMP 协议 2)了解 IP 协议 3)了解 ping 程序的功能
4)
五、实验内容:
六、实验器材(设备、元器件):
PC 机、可利用的程序运行网络环境(可自己搭建,也可直接连接 internet)。

PING实验报告

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程序设计与实现课程设计

ping程序设计与实现课程设计一、课程目标知识目标:1. 学生能理解ping程序的工作原理,掌握网络诊断的基本方法。

2. 学生能描述IP协议、ICMP协议的基本概念及其在ping程序中的应用。

3. 学生了解计算机网络的通信原理,掌握如何利用ping程序检测网络连通性。

技能目标:1. 学生能运用所学知识,独立编写简单的ping程序。

2. 学生通过实践操作,提高问题分析及解决能力,具备基本的网络诊断技巧。

3. 学生掌握使用编程工具(如:IDE、编译器等)进行代码编写、调试和优化。

情感态度价值观目标:1. 学生培养对计算机网络的兴趣,激发学习编程的热情。

2. 学生在学习过程中,培养团队协作、沟通表达的能力,增强自信心。

3. 学生通过本课程的学习,认识到网络技术在实际应用中的重要性,培养对网络安全的责任感。

分析课程性质、学生特点和教学要求,本课程旨在让学生掌握ping程序的设计与实现,结合实际操作,提高学生的编程能力和网络诊断技巧。

课程目标具体、可衡量,有助于教师进行教学设计和评估。

通过本课程的学习,学生将具备基本的网络编程知识和技能,为今后的学习和工作打下坚实基础。

二、教学内容1. 网络基础知识回顾:IP协议、ICMP协议、网络层通信原理。

2. ping程序工作原理:发送ICMP请求、接收ICMP回复、计算往返时间(RTT)。

3. 编程语言基础:C语言或Python语言的基本语法,重点掌握数据类型、控制结构、函数定义。

4. ping程序设计与实现:- 环境搭建:安装编程工具、配置网络环境。

- 代码编写:根据ping程序工作原理,编写发送和接收ICMP请求的代码。

- 调试与优化:调试代码,处理异常情况,优化程序性能。

5. 实践操作:分组进行实际操作,组内讨论、分析问题,相互协作完成ping 程序编写。

6. 网络诊断技巧:运用ping程序检测网络连通性,分析网络延迟、丢包等问题。

教学内容安排和进度:第一课时:网络基础知识回顾,介绍ping程序工作原理。

ping程序的设计与实现

ping程序的设计与实现

ping程序的设计与实现
Ping程序的设计与实现是通过一种单向测量技术来实现的,它可以用来评估网络的性能、访问故障和网络可用性。

Ping程序工作时会首先向目标主机发送一个ICMP(网际控制报文协议)报文,然后等待目标主机的应答。

在实现ping程序的过程中,首先要为发送的ICMP数据报定义一个数据结构,这个数据结构将包含所有必要的信息,如报文类型、报文代码、校验和等。

其次,要实现函数,对这个数据结构进行填充和序列化,以便将ICMP报文发送出去。

实现发送ICMP报文后,就要开始接收应答。

为此,可以利用Socket API来创建一个Raw Socket,以便从网络上接收ICMP报文,并将其解码为数据结构,以便能够识别是哪一条报文的应答。

最后,还需要实现超时,用来处理因网络拥塞或丢包等原因导致的应答报文没有收到的情况。

这可以通过在发送ICMP报文之前先设置一个定时器,当定时器到期时,就可以判断该报文没有收到应答报文而超时。

以上就是ping程序的大致设计与实现方式,整个实现的过程可以大体分为发送ICMP数据报、接收应答和超时处理三部分。

这些都需要对数据报结构进行定义和填充,以及使用Socket API创建Raw Socket 来发送和接收数据,并通过设置定时器来实现超时处理,以保证ping 程序可以正常工作。

Ping 计算机网络课程设计.doc

Ping 计算机网络课程设计.doc

计算机网络课程设计报告设计名称 Ping程序的设计与实现专业班级同组人姓名指导教师成绩一、设计目的和要求1、实验目的利用ICMP数据包、C语言实现Ping命令程序,能实现基本的Ping操作,发送ICMP回显请求报文,用于测试—个主机到只一个主机之间的连通情况。

通过本程序的训练,使学生熟悉ICMP报文结构,使学生对ICMP有更深的理解,掌握Ping程序的设计方法,掌握网络编程的方法和技巧,从而编写出功能更强大的程序。

2、实验要求:输出参考系统自带ping程序,命令行运行:ping ip;二、设计说明1.设计思路由于Ping程序是面向用户的应用程序,该程序使用ICMP的封装机制,通过IP协议来工作。

为了实现直接对IP和ICMP包进行操作,实验中使用RA W模式的socket编程。

首先定义IP数据报首部,在IP数据报的基础上定义ICMP数据报首部,并初始化一些全局变量。

接着自定义填充ICMP数据报字段函数FillICMPData()、校验和函数checksum()、解读ICMP报首部函数DecodeICMPHeader()、释放资源函Cleanup()。

最后主函数通过调用这些函数来实现Ping命令功能。

2.设计方案IP头与ICMP头的设置分别参照RFC791及RFC792的标准,包含所有必要信息。

主程序设置main()函数,主函数用库函数实现套接字编程用于数据包发送及接收,其中,数据包发送调用sendto(),数据包接收调用recvfrom( ),由于发送数据包时可能会遇到阻塞或者目标主机不通,造成超时,因此需要在发送数据包后调用一个函数判断是否超时,此处调用库函数setsockopt()来实现超时判断;其次,校验和函数采用移位方法进行计算。

3. 系统运行环境:VC++ 6.0,Window XP操作系统平台4. 设计中的难点和重点首先遇到的问题就是套接字文件的问题。

套接字所需要的文件有头文件Winsocket2.h、库文件WS2_32.LIB、动态库W32_32.DLL。

ping程序的设计实现分析

ping程序的设计实现分析

计算机网络课程设计任务书计算机网络课程设计说明书学院名称:计算机与信息工程班级名称:学生姓名:学号:题目:基于原始套间字实现简单的ping程序指导教师姓名:起止日期:一、选题背景(标题:四号仿宋加粗,顶格,行间距:24磅,上下间距:段前0.5行,段后0.5行)(内容:用小四号仿宋,首行空两格)通过设计Ping程序,理解Ping程序的实现原理,ping 程序是用来探测主机到主机之间是否可通信,如果不能ping到某台主机,表明不能和这台主机建立连接。

ping 使用的是ICMP协议,它发送ICMP回送请求消息给目的主机。

ICMP 协议规定:目的主机必须返回ICMP回送应答消息给源主机。

如果源主机在一定时间内收到应答,则认为主机可达。

ICMP协议通过IP协议发送的,IP协议是一种无连接的,不可靠的数据包协议。

因此,保证数据送达的工作应该由其他的模块来完成。

其中一个重要的模块就是ICMP(网络控制报文)协议。

二、方案设计(或概要设计)Ping程序可分为四个模块,分别是:初始化(图1-1)、功能控制(图1-2、图1-3、图1-4、)、ping (图1-5)、main测试(图1-6).1.初始化:2.功能控制:图1-2图1-3图1-43.ping:图1-5 4.main()函数:图1-6三、详细设计要实现ping程序,需要实现以下步骤:1.初始化//定义IP首部格式typedef struct _IPHeader{u_char VIHL; //版本和首部长度u_char T oS; //服务类型u_short T otalLen; //总长度u_short ID; //标识号u_short Frag_Flags; //片偏移量u_char TTL; //生存时间u_char Protocol; //协议u_short Checksum; //首部校验和struct in_addr SrcIP; //源IP地址struct in_addr DestIP; //目的地址}IPHDR, *PIPHDR;//定义ICMP首部格式typedef struct _ICMPHeader{u_char T ype; //类型u_char Code; //代码u_short Checksum; //首部校验和u_short ID; //标识u_short Seq; //序列号char Data; //数据}ICMPHDR, *PICMPHDR;//定义ICMP回应请求typedef struct _ECHOREQUEST{ICMPHDR icmpHdr;DWORD dwTime;char cData[REQ_DATASIZE];}ECHOREQUEST, *PECHOREQUEST;//定义ICMP回应答复typedef struct _ECHOREPL Y{IPHDR ipHdr;ECHOREQUEST echoRequest;char cFiller[256];}ECHOREPL Y, *PECHOREPL Y;2.功能//计算校验和函数u_short checksum(u_short *buffer, int len)//发送回应请求函数int SendEchoRequest(SOCKET s, struct sockaddr_in *lpstT oAddr)//接收应答回复并进行解析函数DWORD RecvEchoReply(SOCKET s, LPSOCKADDR_IN lpsaFrom, u_char *pTTL) 3.ping程序//创建原始套接字,ICMP类型实现pingrawSocket = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);//第二个注释函数socketif (rawSocket == SOCKET_ERROR){printf("socket() error:%d\n", WSAGetLastError());return;}四、结果分析(或测试)1.输入ping主机的命令2.输入ping-t命令3.输入外部网主机命令五、总结刚刚拿到课题时,我对于ping几乎没什么了解。

ping程序分析报告

ping程序分析报告

ping程序分析报告ping程序分析报告课程名称:老师:姓名:班级:学号:日期:目录1、Ping功能简介 (1)2、程序流程图(1)主函数流程图 (3)(2)创建套接字流程图 (3)(3)建立IP选项头部流程图 (4)(4)创建SockRaw套接字的接收/发送时限属性流程图 (4)(5)判断终端的主机名获取信息流程图 (5)(6)分配堆内存流程图 (5)(7)接收/发送ICMP数据包流程图 (6)(8)清空Socket库所占内存 (7)(9)传参解析函数流程图 (7)(10)解析IP选项函数流程图 (8)3、源代码清单 (8)4、心得体会 (16)1、ping功能简介Ping 是DOS命令,一般用于检测网络通与不通,也叫时延,其值越大,速度越慢PING (Packet Internet Grope),因特网包探索器,用于测试网络连接量的程序。

Ping发送一个ICMP回声请求消息给目的地并报告是否收到所希望的ICMP回声应答。

它是用来检查网络是否通畅或者网络连接速度的命令。

作为一个生活在网络上的管理员或者黑客来说,ping命令是第一个必须掌握的DOS 命令,它所利用的原理是这样的:网络上的机器都有唯一确定的IP地址,我们给目标IP地址发送一个数据包,对方就要返回一个同样大小的数据包,根据返回的数据包我们可以确定目标主机的存在,可以初步判断目标主机的操作系统等。

Ping 是Windows系列自带的一个可执行命令。

利用它可以检查网络是否能够连通,用好它可以很好地帮助我们分析判定网络故障。

应用格式:Ping IP地址。

该命令还可以加许多参数使用,具体是键入Ping 按回车即可看到详细说明。

ping指的是端对端连通,通常用来作为可用性的检查,但是某些病毒木马会强行大量远程执行ping命令抢占你的网络资源,导致系统变慢,网速变慢。

2、程序流程图①请求版本信息,创建一个套接口②建立IP选项首部③创建SockRaw套接字的接收/发送时限属性失败图1 main函数流程图调用WSAStartup()函数请求版本信息判断其返回值返回值为0,即执行返回值为非0,即执行失败图2创建套接字流程图bRecordRouteTRUE FALSE调用setsockopt()函数,并判断其返回值图3 建立IP选项头部流程图调用setsockopt()函数设置套接字接收时限属性,判断其返回值设置失败设置成功取得错误的进程号,输出错误信息timeout=1000;退出main 函数图4 创建SockRaw套接字的接收/发送时限属性流程图将点分十进制地址转化为二进制地址将该地址赋给dest.sin_addr.s_addr无效地址判断其值有效地址通过主机名获取主机信息图5判断终端的主机名获取信息流程图利用HeapAlloc()分配堆内存函数分配成功分配失败图6 分配堆内存流程图nCount=0nCount++nCount++==4break调用cksum发送ICMP 数据包失败成功图7 接收/发送ICMP数据包流程图套接口是否有效有效无效关闭套接口图8清空Socket库所占内存i=1i<agrc数组argv的第i行第0列是否为‘-’或‘/’’YES NO图9 传参解析函数流程图i=0计算RR选项中记录的地址个数ni<ni!=0NOYES输出空格图10解析IP首部函数流程图3、源代码清单// Module Name: Ping.c#include "windows.h"#include "winsock.h"#include "stdio.h"#define IP_RECORD_ROUTE 0x7 //IP记录路由#define ICMP_ECHO 8 //ICMP回显#define ICMP_ECHOREPLY 0 //ICMP回显应答#define ICMP_MIN 8 //ICMP数据包最小长度#define DEF_PACKET_SIZE 32 //差错报文长度#define MAX_PACKET 0x10000 // ICMP包最大长度#define MAX_IP_HDR_SIZE 60 //IP首部最大字节数//IP头文件定义typedef struct _iphdr{unsigned int h_len:4; //头部长度4字节unsigned int version:4; //IP版本号IPv4unsigned char tos; //服务类型unsigned short total_len; //数据包总长度unsigned short ident; //ID标识unsigned short frag_and_flags; //3位标志,13位片偏移unsigned char ttl; //生存期unsigned char proto; //协议类型unsigned short checksum; //IP头部的检验和unsigned int sourceIP; //源地址unsigned int destIP; //目的地址} IpHeader;//ICMP头部定义typedef struct _icmphdr{BYTE i_type; //ICMP类型(8位)BYTE i_code; //代码类型(8位)USHORT i_cksum; //头部及数据检验和(16位)USHORT i_id;ID//标识USHORT i_seq; //序列号ULONG timestamp; //时间戳} IcmpHeader;//IP选项首部定义typedef struct _ipoptionhdr{unsigned char code; //IP选项的类型unsigned char len; //RR选项总字节长度unsigned char ptr; //指针字段unsigned long addr[9]; // IP地址清单} IpOptionHeader;BOOL bRecordRoute;int datasize;char *lpdest;//定义3个全局变量//使用信息void usage(char *progname){printf("usage: ping -r [data size]\n");printf(" -r record route\n");printf(" host remote machine to ping\n");printf(" datasize can be up to 0x10000 Byte\n");ExitProcess(-1); //结束进程}//ICMP首部初始化void FillICMPData(char *icmp_data, int datasize){IcmpHeader *icmp_hdr = NULL;char *datapart = NULL; //指针定义及初始化icmp_hdr = (IcmpHeader*)icmp_data;icmp_hdr->i_type = ICMP_ECHO; //ICMP回显请求icmp_hdr->i_code = 0;icmp_hdr->i_id = (USHORT)GetCurrentProcessId();//取得当前进程号icmp_hdr->i_cksum = 0; //检验和字段置0icmp_hdr->i_seq = 0;datapart = icmp_data + sizeof(IcmpHeader); //datapart指针指向数据报文开头memset(datapart, 'E', datasize - sizeof(IcmpHeader)); //填充数据段}//计算检验和USHORT checksum(USHORT *buffer, int size){unsigned long cksum = 0; // 检验和字段置0while (size > 1){cksum += *buffer++;size -= sizeof(USHORT);}if (size){cksum += *(UCHAR*)buffer;}cksum = (cksum >> 16) + (cksum & 0xffff);//将检验和字段高16位右移16位再与低16位相加cksum += (cksum >>16);//将所加的检验和再与剩余低16位相加return (USHORT)(~cksum);//检验和取反,并返回}//解析IP选项void DecodeIPOptions(char *buf, int bytes){IpOptionHeader *ipopt = NULL;IN_ADDR inaddr; //声明结构体int i;HOSTENT *host = NULL;ipopt = (IpOptionHeader *)(buf + 20); //去掉IP首部,指针指向数据选项首部printf("RR: ");for(i = 0; i < (ipopt->ptr / 4) - 1; i++){inaddr.S_un.S_addr = ipopt->addr[i];if (i != 0){printf(" ");}host = gethostbyaddr((char *)&inaddr.S_un.S_addr, sizeof(inaddr.S_un.S_addr), AF_INET);//通过IP地址获得主机信息if (host){printf("(%-15s) %s\n", inet_ntoa(inaddr), host->h_name);//打印IP地址和主机名}else{printf("(%-15s)\n", inet_ntoa(inaddr)); //打印IP地址}}return;}//解析ICMP首部函数void DecodeICMPHeader(char *buf, int bytes, struct sockaddr_in *from){IpHeader *iphdr = NULL;IcmpHeader *icmphdr = NULL;unsigned short iphdrlen;DWORD tick; //毫秒级数static int icmpcount = 0;iphdr = (IpHeader *)buf;iphdrlen = iphdr->h_len * 4; //IP首部实际长度tick = GetTickCount();//获得毫秒级数if ((iphdrlen == MAX_IP_HDR_SIZE) && (!icmpcount)) //判断是否为一个IP数据包{DecodeIPOptions(buf, bytes); //调用IP 选项解析函数}if (bytes < iphdrlen + ICMP_MIN)判断IP数据包长度{printf("Too few bytes from %s\n",inet_ntoa(from->sin_addr));}icmphdr = (IcmpHeader*)(buf + iphdrlen); //指针指向ICMP报文首部if (icmphdr->i_type != ICMP_ECHOREPLY) //判断ICMP类型是否为ICMP回显应答{printf("nonecho type %d recvd\n", icmphdr->i_type); //输出其类型return;}if (icmphdr->i_id != (USHORT)GetCurrentProcessId())//获得当前进程的ID,判断是否为ICMP标识{printf("someone else's packet!\n");return ;}printf("%d bytes from %s:", bytes, inet_ntoa(from->sin_addr));printf(" icmp_seq = %d. ", icmphdr->i_seq); //输出ICMP序列号printf(" time: %d ms", tick - icmphdr->timestamp); //打印时间戳printf("\n");icmpcount++;return;}//传参解析函数void ValidateArgs(int argc, char **argv){int i;bRecordRoute = FALSE;赋初值lpdest = NULL;datasize = DEF_PACKET_SIZE; //初始化datasize,使其等于差错报文长度for(i = 1; i < argc; i++){if ((argv[i][0] == '-') || (argv[i][0] == '/')) //判断数组argv第i行第0列是否为‘-’或‘/’{switch (tolower(argv[i][1])) //将数组argv第i行第1列的字符转化为小写字母{case 'r': //记录路由选项bRecordRoute = TRUE;break;default:usage(argv[0]);调用usage函数break;}}else if (isdigit(argv[i][0])) //判断数组argv第i行第0列是否为数字{datasize = atoi(argv[i]); //将数组argv第i 行的字符转化成长整型数}else{lpdest = argv[i];}}}//main函数int main(int argc, char **argv) // argc代表命令行中的参数个数,* *argv 是指向字符串的指针{char *icmp_data = NULL;char *recvbuf = NULL;USHORT seq_no = 0;//定义及初始化struct sockaddr_in dest = {'\0'};struct sockaddr_in from= {'\0'};struct hostent *hp = NULL;//声明结构体int bread = 0;int ret = 0;int fromlen = sizeof(from);int timeout = 1000;unsigned int addr = 0;//定义及初始化WSADATA wsaData; //声明数据结构SOCKET sockRaw = INV ALID_SOCKET;IpOptionHeader ipopt = {'\0'};if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)//指明程序请求使用的socket版本,返回请求的版本信息{printf("WSAStartup() failed: %d\n", GetLastError());//获得当前的进程错误号,并输出“请求版本信息失败”return 2;}ValidateArgs(argc, argv);//调用传参解析函数sockRaw = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);//创建sockRaw套接字if (sockRaw == INV ALID_SOCKET)//创建失败{printf("WSASocket() failed: %d\n", WSAGetLastError());return 3;//返回值3,并退出main函数}if (bRecordRoute){ZeroMemory(&ipopt, sizeof(ipopt));ipopt.code = IP_RECORD_ROUTE;ipopt.ptr = 4; //指向第一个地址列表ipopt.len = 39;ret = setsockopt(sockRaw, IPPROTO_IP, IP_OPTIONS,(char *)&ipopt, sizeof(ipopt));// 设置sockRaw套接字属性if (ret == SOCKET_ERROR)//设置属性失败{printf("setsockopt(IP_OPTIONS) failed: %d\n",WSAGetLastError());//取得当前错误进程号,并输出“属性设置失败”}}bread = setsockopt(sockRaw, SOL_SOCKET, SO_RCVTIMEO,(char*)&timeout, sizeof(timeout));//设置套接字接收时限属性if(bread == SOCKET_ERROR)//设置失败{printf("setsockopt(SO_RCVTIMEO) failed: %d\n",WSAGetLastError());return -1;返回值-1,并退出main函数}timeout = 1000;bread = setsockopt(sockRaw, SOL_SOCKET, SO_SNDTIMEO,(char*)&timeout, sizeof(timeout));//设置套接字发送时限属性if (bread == SOCKET_ERROR)//设置发送时限失败{printf("setsockopt(SO_SNDTIMEO) failed: %d\n",WSAGetLastError());return -1; 返回值-1,并退出main函数}memset(&dest, 0, sizeof(dest));//填充数据段,dest.sin_family = AF_INET;//指定地址族if ((dest.sin_addr.s_addr = inet_addr(lpdest)) == INADDR_NONE)//网络地址是无效的地址{if ((hp = gethostbyname(lpdest)) != NULL){memcpy(&(dest.sin_addr), hp->h_addr, hp->h_length);dest.sin_family = hp->h_addrtype;将hp->h_addrtype的类型赋给dest.sin_familyprintf("dest.sin_addr = %s\n", inet_ntoa(dest.sin_addr));//输出IP地址}else{printf("gethostbyname() failed: %d\n",WSAGetLastError());return -1;退出main函数,并返回值-1}}datasize += sizeof(IcmpHeader);icmp_data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, MAX_PACKET);//分配堆内存recvbuf = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, MAX_PACKET);if (!icmp_data)//分配失败{printf("HeapAlloc() failed: %d\n", GetLastError());//获得当前错误进程号,输出“堆内存分配失败”return -1; //退出main函数,并返回值-1}memset(icmp_data,0,MAX_PACKET);//填充数据段FillICMPData(icmp_data,datasize);//调用ICMP 初始化函数while(1){static int nCount = 0; //初始化int bwrote;if (nCount++ == 4){break;结束整个循环}((IcmpHeader*)icmp_data)->i_cksum = 0;((IcmpHeader*)icmp_data)->timestamp = GetTickCount();//设定时间戳((IcmpHeader*)icmp_data)->i_seq = seq_no++;//设置ICMP头部序列号((IcmpHeader*)icmp_data)->i_cksum =checksum((USHORT*)icmp_data, datasize);//调用计算检验和函数,将其返回值赋给i_cksumbwrote = sendto(sockRaw, icmp_data, datasize, 0,(struct sockaddr*)&dest, sizeof(dest)); //发送ICMP数据包if (bwrote == SOCKET_ERROR) //发送失败{if (WSAGetLastError() == WSAETIMEDOUT) //当前错误进程号为超时{printf("timed out\n");continue; //结束本次循环}printf("sendto() failed: %d\n", WSAGetLastError());return -1; //退出main函数,并返回值-1}if (bwrote < datasize)//已发送字节数小于datasize{printf("Wrote %d bytes\n", bwrote);}bread = recvfrom(sockRaw, recvbuf, MAX_PACKET, 0, (struct sockaddr*)&from, &fromlen);// 接收ICMP数据包if (bread == SOCKET_ERROR) //接收失败{if (WSAGetLastError() == WSAETIMEDOUT) //当前错误进程号为超时{printf("timed out\n");continue; //结束本次循环}printf("recvfrom() failed: %d\n", WSAGetLastError());return -1; 退出main函数,并返回值-1}DecodeICMPHeader(recvbuf, bread, &from); //调用解析ICMP头部函数Sleep(1000);//暂停1000ms}if (sockRaw != INV ALID_SOCKET) //套接字有效{closesocket(sockRaw); //关闭套接字}HeapFree(GetProcessHeap(), 0, recvbuf);HeapFree(GetProcessHeap(), 0, icmp_data); //释放堆内存WSACleanup();//应用程序完成对请求的Socket库的使用调用WSACleanup()函数来解除与Socket库的绑定并释放Socket库所占的系统资源return 0; //退出main函数,并返回值0}五、心得体会了解Ping程序的运行过程;了解程序如何实现检验和的计算,当程序发送数据时需要计算其检验和并放到检验和字段中,当计算检验和时首先将数据中各16字段相加,为避免存在进位,将计算结果的高16位和低16位反复相加,直到高位中部存在进位,将结果取返存入检建验和字段。

ping程序设计与实现

ping程序设计与实现

测试结果如下:
1.
2.
错误分析:
1. Request Timed Out a.提到的对方可能装有防火墙或已关机以外,还有就是本机的IP不正确和网关设置错误。 b.IP不正确:IP不正确主要是IP地址设置错误或IP地址冲突。
2. Destination Host Unreachable
a.如果局域网中使用DHCP分配IP时,而碰巧DHCP失效,这时使用 PING命令就会产 生此错误。
1.初始化模块 2.功能控制模块 3.数据控制模块 4.数据 Nhomakorabea解读模块
5. ping测试模块
程序测试:
1. Ping127.0.0.1,127.0.0.1回送地址Ping回送地址是为了检 查本地的TCP/IP协议有没有设置好。 2. Ping远程IP地址,这主要是检查本网或本机与外部的连接是否 正常。
ping的程序设计与实现
1.设计目的:本程序设计主要解决在本地的电脑上去 查看别的网站和本机电脑的连通性,检查本机是否可以 在浏览器上访问到该网站。
2.开发平台:在课程设计中,系统开发平台为
Windows xp或者Windows 7,程序设计设计语言采 用Visual C++来实现。
本程序设计的五个模块:
b.另外子网掩码设置错误也会出现这错误。
c.比较特殊就是路由返回错误信息,它一般都会在"Destination Host Unreachable"前加 上IP地址说明哪个路由不能到达目标主机。这说明你的机器与外部网络连接没有问题, 但与某台主机连接存在问题。
谢谢各评委老师 以及在座的小伙伴们!

计算机网络ping命令实验报告

计算机网络ping命令实验报告

课程实验报告
实验课程网络及其计算实验
实验名称 ping命令实验
实验地点
实验时间
学生班级
学生学号
学生姓名
XXXX年 XX 月 XX 日
实验目的:
(1)掌握ping命令及常用参数的用法。

实验器材:
一台连网的Windows操作系统的PC机。

实验内容:
使用ping命令及各常用参数去ping一些站点,观察并分析结果。

实验结果(附数据和图表):
打开运行窗口,快捷键windows键+R,输入cmd
ping命令
1.输入ping /?(得到ping命令使用方法)
2.ping+网址
3.ping -t +网址Ctrl+C时停止
4.ping -n count 衡量网络速度
5.ping -l size
实验结果分析及结论:
Ping命令基于ICMP协议,在源站点执行,向目的站点发送ICMP回送请求报文,目的站点在收到报文后向源站点返回ICMP回送回答报文,源站点把返回的结果信息显示出来。

该命令用于测试站点之间是否可达,若可达,则可进一步判断双方的通信质量包括稳定性等。

实验心得体会和建议:
通过本次实验简单的了解了ping命令的使用方法以及地址问题,注意到网络之间的安全性,对网络有了更深刻的认识。

在解决实验中发生的问题时,更让人具有成就感和继续学习的渴望。

实验评价及结论:
实验指导老师签字:年月日。

ping程序分析报告(word文档良心出品)

ping程序分析报告(word文档良心出品)

ping程序分析报告姓名:班级:学号:目录1、Ping功能简介 (1)2、程序流程图(1)主函数流程图 (3)(2)创建套接字流程图 (3)(3)建立IP选项头部流程图 (4)(4)创建SockRaw套接字的接收/发送时限属性流程图 (4)(5)判断终端的主机名获取信息流程图 (5)(6)分配堆内存流程图 (5)(7)接收/发送ICMP数据包流程图 (6)(8)清空Socket库所占内存 (7)(9)传参解析函数流程图 (7)(10)解析IP选项函数流程图 (8)3、源代码清单 (8)4、心得体会 (16)1、ping功能简介Ping是DOS命令,一般用于检测网络通与不通,也叫时延,其值越大,速度越慢PING (Packet Internet Grope),因特网包探索器,用于测试网络连接量的程序。

Ping发送一个ICMP回声请求消息给目的地并报告是否收到所希望的ICMP回声应答。

它是用来检查网络是否通畅或者网络连接速度的命令。

作为一个生活在网络上的管理员或者黑客来说,ping命令是第一个必须掌握的DOS 命令,它所利用的原理是这样的:网络上的机器都有唯一确定的IP地址,我们给目标IP地址发送一个数据包,对方就要返回一个同样大小的数据包,根据返回的数据包我们可以确定目标主机的存在,可以初步判断目标主机的操作系统等。

Ping 是Windows系列自带的一个可执行命令。

利用它可以检查网络是否能够连通,用好它可以很好地帮助我们分析判定网络故障。

应用格式:Ping IP地址。

该命令还可以加许多参数使用,具体是键入Ping 按回车即可看到详细说明。

ping指的是端对端连通,通常用来作为可用性的检查,但是某些病毒木马会强行大量远程执行ping命令抢占你的网络资源,导致系统变慢,网速变慢。

2、程序流程图图1 main函数流程图图2创建套接字流程图图3 建立IP选项头部流程图图4 创建SockRaw套接字的接收/发送时限属性流程图图5判断终端的主机名获取信息流程图图6 分配堆内存流程图图7 接收/发送ICMP数据包流程图图8清空Socket库所占内存图9 传参解析函数流程图图10解析IP首部函数流程图3、源代码清单// Module Name: Ping.c#include "windows.h"#include "winsock.h"#include "stdio.h"#define IP_RECORD_ROUTE 0x7 //IP记录路由#define ICMP_ECHO 8 //ICMP回显#define ICMP_ECHOREPLY 0 //ICMP回显应答#define ICMP_MIN 8 //ICMP数据包最小长度#define DEF_PACKET_SIZE 32 //差错报文长度#define MAX_PACKET 0x10000 // ICMP包最大长度#define MAX_IP_HDR_SIZE 60 //IP首部最大字节数//IP头文件定义typedef struct _iphdr{unsigned int h_len:4; //头部长度4字节unsigned int version:4; //IP版本号IPv4unsigned char tos; //服务类型unsigned short total_len; //数据包总长度unsigned short ident; //ID标识unsigned short frag_and_flags; //3位标志,13位片偏移unsigned char ttl; //生存期unsigned char proto; //协议类型unsigned short checksum; //IP头部的检验和unsigned int sourceIP; //源地址unsigned int destIP; //目的地址} IpHeader;//ICMP头部定义typedef struct _icmphdr{BYTE i_type; //ICMP类型(8位)BYTE i_code; //代码类型(8位)USHORT i_cksum; //头部及数据检验和(16位)USHORT i_id;ID//标识USHORT i_seq; //序列号ULONG timestamp; //时间戳} IcmpHeader;//IP选项首部定义typedef struct _ipoptionhdr{unsigned char code; //IP选项的类型unsigned char len; //RR选项总字节长度unsigned char ptr; //指针字段unsigned long addr[9]; // IP地址清单} IpOptionHeader;BOOL bRecordRoute;int datasize;char *lpdest;//定义3个全局变量//使用信息void usage(char *progname){printf("usage: ping -r [data size]\n");printf(" -r record route\n");printf(" host remote machine to ping\n");printf(" datasize can be up to 0x10000 Byte\n");ExitProcess(-1); //结束进程}//ICMP首部初始化void FillICMPData(char *icmp_data, int datasize){IcmpHeader *icmp_hdr = NULL;char *datapart = NULL; //指针定义及初始化icmp_hdr = (IcmpHeader*)icmp_data;icmp_hdr->i_type = ICMP_ECHO; //ICMP回显请求icmp_hdr->i_code = 0;icmp_hdr->i_id = (USHORT)GetCurrentProcessId();//取得当前进程号icmp_hdr->i_cksum = 0; //检验和字段置0icmp_hdr->i_seq = 0;datapart = icmp_data + sizeof(IcmpHeader); //datapart指针指向数据报文开头memset(datapart, 'E', datasize - sizeof(IcmpHeader)); //填充数据段}//计算检验和USHORT checksum(USHORT *buffer, int size){unsigned long cksum = 0; // 检验和字段置0while (size > 1){cksum += *buffer++;size -= sizeof(USHORT);}if (size){cksum += *(UCHAR*)buffer;}cksum = (cksum >> 16) + (cksum & 0xffff);//将检验和字段高16位右移16位再与低16位相加cksum += (cksum >>16);//将所加的检验和再与剩余低16位相加return (USHORT)(~cksum);//检验和取反,并返回}//解析IP选项void DecodeIPOptions(char *buf, int bytes){IpOptionHeader *ipopt = NULL;IN_ADDR inaddr; //声明结构体int i;HOSTENT *host = NULL;ipopt = (IpOptionHeader *)(buf + 20); //去掉IP首部,指针指向数据选项首部printf("RR: ");for(i = 0; i < (ipopt->ptr / 4) - 1; i++){inaddr.S_un.S_addr = ipopt->addr[i];if (i != 0){printf(" ");}host = gethostbyaddr((char *)&inaddr.S_un.S_addr, sizeof(inaddr.S_un.S_addr), AF_INET);//通过IP地址获得主机信息if (host){printf("(%-15s) %s\n", inet_ntoa(inaddr), host->h_name);//打印IP地址和主机名}else{printf("(%-15s)\n", inet_ntoa(inaddr)); //打印IP地址}}return;}//解析ICMP首部函数void DecodeICMPHeader(char *buf, int bytes, struct sockaddr_in *from){IpHeader *iphdr = NULL;IcmpHeader *icmphdr = NULL;unsigned short iphdrlen;DWORD tick; //毫秒级数static int icmpcount = 0;iphdr = (IpHeader *)buf;iphdrlen = iphdr->h_len * 4; //IP首部实际长度tick = GetTickCount();//获得毫秒级数if ((iphdrlen == MAX_IP_HDR_SIZE) && (!icmpcount)) //判断是否为一个IP数据包{DecodeIPOptions(buf, bytes); //调用IP 选项解析函数}if (bytes < iphdrlen + ICMP_MIN)判断IP数据包长度{printf("Too few bytes from %s\n",inet_ntoa(from->sin_addr));}icmphdr = (IcmpHeader*)(buf + iphdrlen); //指针指向ICMP报文首部if (icmphdr->i_type != ICMP_ECHOREPLY) //判断ICMP类型是否为ICMP回显应答{printf("nonecho type %d recvd\n", icmphdr->i_type); //输出其类型return;}if (icmphdr->i_id != (USHORT)GetCurrentProcessId())//获得当前进程的ID,判断是否为ICMP标识{printf("someone else's packet!\n");return ;}printf("%d bytes from %s:", bytes, inet_ntoa(from->sin_addr));printf(" icmp_seq = %d. ", icmphdr->i_seq); //输出ICMP序列号printf(" time: %d ms", tick - icmphdr->timestamp); //打印时间戳printf("\n");icmpcount++;return;}//传参解析函数void ValidateArgs(int argc, char **argv){int i;bRecordRoute = FALSE;赋初值lpdest = NULL;datasize = DEF_PACKET_SIZE; //初始化datasize,使其等于差错报文长度for(i = 1; i < argc; i++){if ((argv[i][0] == '-') || (argv[i][0] == '/')) //判断数组argv第i行第0列是否为‘-’或‘/’{switch (tolower(argv[i][1])) //将数组argv第i行第1列的字符转化为小写字母{case 'r': //记录路由选项bRecordRoute = TRUE;break;default:usage(argv[0]);调用usage函数break;}}else if (isdigit(argv[i][0])) //判断数组argv第i行第0列是否为数字{datasize = atoi(argv[i]); //将数组argv第i 行的字符转化成长整型数}else{lpdest = argv[i];}}}//main函数int main(int argc, char **argv) // argc代表命令行中的参数个数,* *argv 是指向字符串的指针{char *icmp_data = NULL;char *recvbuf = NULL;USHORT seq_no = 0;//定义及初始化struct sockaddr_in dest = {'\0'};struct sockaddr_in from= {'\0'};struct hostent *hp = NULL;//声明结构体int bread = 0;int ret = 0;int fromlen = sizeof(from);int timeout = 1000;unsigned int addr = 0;//定义及初始化WSADATA wsaData; //声明数据结构SOCKET sockRaw = INVALID_SOCKET;IpOptionHeader ipopt = {'\0'};if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)//指明程序请求使用的socket版本,返回请求的版本信息{printf("WSAStartup() failed: %d\n", GetLastError());//获得当前的进程错误号,并输出“请求版本信息失败”return 2;}ValidateArgs(argc, argv);//调用传参解析函数sockRaw = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);//创建sockRaw套接字if (sockRaw == INV ALID_SOCKET)//创建失败{printf("WSASocket() failed: %d\n", WSAGetLastError());return 3;//返回值3,并退出main函数}if (bRecordRoute){ZeroMemory(&ipopt, sizeof(ipopt));ipopt.code = IP_RECORD_ROUTE;ipopt.ptr = 4; //指向第一个地址列表ipopt.len = 39;ret = setsockopt(sockRaw, IPPROTO_IP, IP_OPTIONS,(char *)&ipopt, sizeof(ipopt));// 设置sockRaw套接字属性if (ret == SOCKET_ERROR)//设置属性失败{printf("setsockopt(IP_OPTIONS) failed: %d\n",WSAGetLastError());//取得当前错误进程号,并输出“属性设置失败”}}bread = setsockopt(sockRaw, SOL_SOCKET, SO_RCVTIMEO,(char*)&timeout, sizeof(timeout));//设置套接字接收时限属性if(bread == SOCKET_ERROR)//设置失败{printf("setsockopt(SO_RCVTIMEO) failed: %d\n",WSAGetLastError());return -1;返回值-1,并退出main函数}timeout = 1000;bread = setsockopt(sockRaw, SOL_SOCKET, SO_SNDTIMEO,(char*)&timeout, sizeof(timeout));//设置套接字发送时限属性if (bread == SOCKET_ERROR)//设置发送时限失败{printf("setsockopt(SO_SNDTIMEO) failed: %d\n",WSAGetLastError());return -1; 返回值-1,并退出main函数}memset(&dest, 0, sizeof(dest));//填充数据段,dest.sin_family = AF_INET;//指定地址族if ((dest.sin_addr.s_addr = inet_addr(lpdest)) == INADDR_NONE)//网络地址是无效的地址{if ((hp = gethostbyname(lpdest)) != NULL){memcpy(&(dest.sin_addr), hp->h_addr, hp->h_length);dest.sin_family = hp->h_addrtype;将hp->h_addrtype的类型赋给dest.sin_familyprintf("dest.sin_addr = %s\n", inet_ntoa(dest.sin_addr));//输出IP地址}else{printf("gethostbyname() failed: %d\n",WSAGetLastError());return -1;退出main函数,并返回值-1}}datasize += sizeof(IcmpHeader);icmp_data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, MAX_PACKET);//分配堆内存recvbuf = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, MAX_PACKET);if (!icmp_data)//分配失败{printf("HeapAlloc() failed: %d\n", GetLastError());//获得当前错误进程号,输出“堆内存分配失败”return -1; //退出main函数,并返回值-1}memset(icmp_data,0,MAX_PACKET);//填充数据段FillICMPData(icmp_data,datasize);//调用ICMP 初始化函数while(1){static int nCount = 0; //初始化int bwrote;if (nCount++ == 4){break;结束整个循环}((IcmpHeader*)icmp_data)->i_cksum = 0;((IcmpHeader*)icmp_data)->timestamp = GetTickCount();//设定时间戳((IcmpHeader*)icmp_data)->i_seq = seq_no++;//设置ICMP头部序列号((IcmpHeader*)icmp_data)->i_cksum =checksum((USHORT*)icmp_data, datasize);//调用计算检验和函数,将其返回值赋给i_cksumbwrote = sendto(sockRaw, icmp_data, datasize, 0,(struct sockaddr*)&dest, sizeof(dest)); //发送ICMP数据包if (bwrote == SOCKET_ERROR) //发送失败{if (WSAGetLastError() == WSAETIMEDOUT) //当前错误进程号为超时{printf("timed out\n");continue; //结束本次循环}printf("sendto() failed: %d\n", WSAGetLastError());return -1; //退出main函数,并返回值-1}if (bwrote < datasize)//已发送字节数小于datasize{printf("Wrote %d bytes\n", bwrote);}bread = recvfrom(sockRaw, recvbuf, MAX_PACKET, 0, (struct sockaddr*)&from, &fromlen);// 接收ICMP数据包if (bread == SOCKET_ERROR) //接收失败{if (WSAGetLastError() == WSAETIMEDOUT) //当前错误进程号为超时{printf("timed out\n");continue; //结束本次循环}printf("recvfrom() failed: %d\n", WSAGetLastError());return -1; 退出main函数,并返回值-1}DecodeICMPHeader(recvbuf, bread, &from); //调用解析ICMP头部函数Sleep(1000);//暂停1000ms}if (sockRaw != INV ALID_SOCKET) //套接字有效{closesocket(sockRaw); //关闭套接字}HeapFree(GetProcessHeap(), 0, recvbuf);HeapFree(GetProcessHeap(), 0, icmp_data); //释放堆内存WSACleanup();//应用程序完成对请求的Socket库的使用调用WSACleanup()函数来解除与Socket库的绑定并释放Socket库所占的系统资源return 0; //退出main函数,并返回值0}五、心得体会了解Ping程序的运行过程;了解程序如何实现检验和的计算,当程序发送数据时需要计算其检验和并放到检验和字段中,当计算检验和时首先将数据中各16字段相加,为避免存在进位,将计算结果的高16位和低16位反复相加,直到高位中部存在进位,将结果取返存入检验和字段。

Ping 程序设计原理

Ping 程序设计原理

Ping 程序设计原理Ping 程序设计原理1. 简介Ping(Packet Internet Groper)是一种基于 ICMP 协议的网络诊断工具,用于主机之间的连通性和网络延迟。

Ping 命令通过发送 ICMP ECHO_REQUEST 数据包到目标主机,并等待目标主机返回ICMP ECHO_REPLY 数据包来网络连接状态。

本文将介绍 Ping 程序的设计原理和实现方式。

2. 设计原理Ping 程序的设计原理可以分为两个部分:数据包的发送和接收。

2.1 数据包的发送当用户在终端输入 `ping 目标主机地质` 命令后,Ping 程序需要解析用户输入的目标主机地质,获取目标主机的 IP 地质。

然后,Ping 程序构造一个 ICMP ECHO_REQUEST 数据包,并将其发送到目标主机的 IP 地质。

在构造 ICMP ECHO_REQUEST 数据包时,Ping 程序需要设置相应的字段,包括类型、代码、校验和等。

其中,类型字段用于指定数据包类型为请求报文,代码字段一般设置为 0,校验和字段用于验证数据包完整性。

发送 ICMP ECHO_REQUEST 数据包时,Ping 程序需要调用底层的网络库,将数据包发送到目标主机的 IP 地质。

发送数据包后,Ping 程序等待目标主机返回 ICMP ECHO_REPLY 数据包。

2.2 数据包的接收Ping 程序在发送 ICMP ECHO_REQUEST 数据包后,会进入接收状态,等待目标主机返回 ICMP ECHO_REPLY 数据包。

当 Ping 程序接收到目标主机返回的 ICMP ECHO_REPLY 数据包时,会计算网络延迟,并将结果显示在终端上。

在接收 ICMP ECHO_REPLY 数据包时,Ping 程序需要调用底层的网络库,监听网络接口,等待数据包的到达。

当接收到 ICMP ECHO_REPLY 数据包时,Ping 程序需要校验数据包的完整性,并提取出其中的字段,包括类型、代码、校验和等。

ping程序的设计实现分析范文

ping程序的设计实现分析范文

精品文档滁州学院课程设计报告课程名称:计算机网络课程设计设计题目ping程序的设计与实现:系别:计算机与信息工程学院专业:计算科学与技术组别:第五小组~2011年12月812月1日日2011起止日期:年指导教师:计算机科学与技术系二○一一年制.精品文档课程设计任务书.精品文档一.Ping 程序运行原理在网络层,除了IP协议之外,还有一些控制协议,如ICMP,ARP, DHCP等。

1.ping的基础知识原始套接字原始套接字是允许访问底层传输协议的一种套接字类型。

使用原始套接字操作IP数据报,可以进行路由跟踪,Ping等。

另外,使用原始套接字需要知道许多下层协议结构的知识,所以下面讨论ICMP,IP, UDP, TCP格式。

原始套接字有两种类型,第一种类型是在IP头种使用预定义的协议,如ICMP;第二种类型是在IP头种使用自定义的协议。

下面使用创建原始套接字的方法。

创建套接字的函数是socket()或者WSASocket(),只不过要将套接字类型指定为SOCK_RAW,代码如下:SOCKET sraw = ::socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);创建原始套接字时socket函数的第三个参数protocol值将成为IP头中得协议域的值。

IPPROTO_ICMP指定要使用ICMP。

原始套解释提供管理下层传输的能力。

他们可能会被恶意利用,因此,仅Administrator组的成员能够创建SOCK_RAW类型的套接字。

任何人在Windows NT下都可以创建原始套接字,但是没有Administrator权限的人不能用它来做任何事情,因为bind函数将会失败,出错码WSAEACCES..在上面的套接字创建代码种,我们使用ICMP,也可以使用IIGMP, UDP, IP或者原始IP,对应的宏定义分别是IPPROTO_IGMP, IPROTO_UDP, IPPROTO_IP或者IPPROTO_RAW。

ping程序的设计实现分析范文

ping程序的设计实现分析范文

滁州学院课程设计报告课程名称:计算机网络课程设计设计题目:ping程序的设计与实现系别:计算机与信息工程学院专业:计算科学与技术组别:第五小组起止日期:2011年12月1日~2011年12月8日指导教师:计算机科学与技术系二○一一年制课程设计任务书一.Ping 程序运行原理在网络层,除了IP协议之外,还有一些控制协议,如ICMP,ARP, DHCP等。

1.ping的基础知识原始套接字原始套接字是允许访问底层传输协议的一种套接字类型。

使用原始套接字操作IP数据报,可以进行路由跟踪,Ping等。

另外,使用原始套接字需要知道许多下层协议结构的知识,所以下面讨论ICMP,IP, UDP, TCP格式。

原始套接字有两种类型,第一种类型是在IP头种使用预定义的协议,如ICMP;第二种类型是在IP头种使用自定义的协议。

下面使用创建原始套接字的方法。

创建套接字的函数是socket()或者WSASocket(),只不过要将套接字类型指定为SOCK_RAW,代码如下:SOCKET sraw = ::socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);创建原始套接字时socket函数的第三个参数protocol值将成为IP头中得协议域的值。

IPPROTO_ICMP指定要使用ICMP。

原始套解释提供管理下层传输的能力。

他们可能会被恶意利用,因此,仅Administrator组的成员能够创建SOCK_RAW类型的套接字。

任何人在Windows NT下都可以创建原始套接字,但是没有Administrator权限的人不能用它来做任何事情,因为bind函数将会失败,出错码WSAEACCES..在上面的套接字创建代码种,我们使用ICMP,也可以使用IIGMP, UDP, IP或者原始IP,对应的宏定义分别是IPPROTO_IGMP, IPROTO_UDP, IPPROTO_IP或者IPPROTO_RAW。

计算机网络实验报告--两次ping命令分析

计算机网络实验报告--两次ping命令分析
ARP应答包也在MAC协议中发送。
两次执行ping命令前,PC中ARP高速缓存内容有无区别(注:可利用ARP –a命令查询高速缓存内容)?
第一次执行之前无ARP缓存,输入命令显示无效的地址;
第二次执行前有ARP缓存,输入显示192.168.152.172及其MAC地址。
回答问题
总结ARP协议的工作原理。
实验目的
1、理解计算机网络体系结构中层与层之间的封装。
2、掌握局域网的MAC(介质访问控制)协议,掌握ARP协议的工作机制,掌握ping命令使用的ICMP报文类型和发送方法。
3、掌握对协议数据单元的分析方法。
实验步骤
1、利用实验室中现有以太网络,分别利用IPConfig命令查阅两台PC机的IP地址。
试说出ping命令执行时,发送的echo请求和echo应答的报文类型。解析报文中各字段的含义。回答报文的底层封装协议各是什么。
主机(155)向另一台主机(172)发送请求,然后主机172向主机155做出应答。
然后一共四对这样的请求应答包。
报文底层协议分别是ICMP(request)和ICMP(reply)
Hardware type(硬件类型):以太网,大小为6字节;
Protocol type(协议类型):IP,大小为4字节。
发送方显示有对方的MAC地址(00:01:6c:97:6e:c5)和IP地址(192.168.152.172);
接收方显示有本机的MAC地址(00:01:6c:97:70:44)和IP地址(192.168.152.155);
Source:192.168.152.172(源地址)
Destination:192.168.152.155(目的地址)
目标MAC地址

计算机网络实验之Ping程序地设计与实现

计算机网络实验之Ping程序地设计与实现

课程名称计算机网络实验序号实验五实验项目Ping程序的设计与实现2017年03月25 日实验报告要求1、实验报告封面填表说明(每份实验报告必须附上封面)(1)课程名称:要求与实验大纲和实验指导书中的课程名称一致。

(2)实验序号:指该课程的第几个实验。

(3)实验项目:要求与实验大纲和实验指导书中的实验项目一致。

(4)实验地点:填写完成该实验项目所在的实验室名称。

(5)实验学时:要求与实验大纲和实验指导书中完成该实验项目所需学时一致。

(6)实验类型:是指演示性、操作性、验证性、综合性、设计性。

演示性:教师操作,学生观察,验证理论、说明原理和方法。

操作性:学生按要求动手拆装、调试实验装置或上机操作,掌握其基本原理和方法。

验证性:按实验指导书(教材)要求,由学生通过操作验证所学理论,加深对理论、知识的理解,掌握基本实验知识、方法、技能、数据处理等。

综合性:实验内容涉及本课程的综合知识或相关课程的知识,运用多的知识、多种方法,按要求或自拟实验方案进行实验。

主要培养学生综合运用所学知识、实验方法和实验技能,以培养其分析、解决问题的能力。

设计性:给定实验目的、要求和实验条件,学生自己设计实验方案并加以实现的实验。

学生独立完成从查阅资料、拟定实验方案、实验方法和步骤(或系统分析和设计)、选择仪器设备(或自行设计缺制作)进行实验并完成实验全过程,形成实验报告,培养学生自主实验的能力。

2、实验报告的格式3、教师批改学生实验报告要求(1)批改:全部批改及更正错误。

(2)评分:按百分制评分,不能评分为“优、良、中、差”或“A、B、C”。

(3)签名及批改日期:任课教师必须在每份学生实验报告中签名和写上批改日期。

(4)成绩:填写学生实验成绩表,实验成绩作为考试成绩评定的依据。

(4)评语:任课教师批改学生实验报告时,应给出简明扼要的评语。

二、实验原理与内容1、一种网络诊断工具2、发送ICMP回送请求报文3、接收ICMP回送应答报文4、IP报文格式5、WinSock原始套接字的使用方法与API函数W insock原始套接字编程过程中,服务器端/客户端的编程都按照以下步骤:初始化套接字(WSAStartup)创建套接字(socket或WSASocket)向服务器通信(sendto/recvfrom)关闭套接字(closesocket)结束使用套接字(WSACleanup)6、三种WinSock地址结构①用的Winsock地址结构sockaddr ,针对各种通信域的套接字,存储它们的地址信息。

Ping 程序设计原理

Ping 程序设计原理

Ping 程序设计原理Ping 程序设计原理一、概述Ping 程序是计算机网络中的一种常见工具,用于测试主机之间的可达性。

它通过向目标主机发送一个ICMP Echo请求,并等待目标主机返回一个ICMP Echo响应来判断目标主机是否能够正常响应。

Ping 程序的设计原理主要包括以下几个方面:ICMP协议、Ping数据包的构造、数据包的发送与接收、计时与统计等。

二、ICMP协议Ping 程序使用的是ICMP(Internet Control Message Protocol)协议。

ICMP是TCP/IP协议族中的一个子协议,用于在IP网络中传递错误、控制和信息性消息。

Ping程序利用ICMP协议中的Echo请求和Echo响应消息来测试主机的可达性。

三、Ping数据包的构造Ping 程序发送的数据包通常是一个ICMP Echo请求数据包。

ICMP Echo请求数据包一般由一个ICMP头和一段Payload数据构成。

ICMP头中包含了一些必要的字段,如类型、代码、校验和等。

Payload部分一般包含具体的Ping数据,Ping程序发送的数据包中一般会包含一个序列号字段和一个时间戳字段。

四、数据包的发送与接收在发送Ping数据包时,Ping程序会使用底层的网络套接字API 向目标主机发送ICMP Echo请求数据包。

发送数据包后,程序会等待一段时间来接收目标主机的响应数据包。

如果接收到了相应的ICMP Echo响应数据包,程序会将接收到的数据包解析出来,并计算网络延迟(Round-Trip Time)和丢包率等统计信息。

五、计时与统计Ping程序中的计时与统计功能通常用来评估网络连接的质量。

程序会记录每个发送的数据包的发送时间戳,并在接收到相应的ICMP Echo响应数据包后,再记录下接收时间戳。

通过计算发送和接收时间戳之间的差值,可以得到网络延迟。

程序还会统计发送和接收的数据包数量,以及丢包率等信息。

Ping程序设计代码及报告

Ping程序设计代码及报告

实验报告
课程计算机网络课程设计实验名称Ping程序的设计与实现专业班级08级信管(2)班
姓名
学号**********
实验日期2011年11月8日
System.gc();
end=System.currentTimeMillis();
}
public long duration()//计算响应时间的方法
{
return(end-start);
}
public void reset()//重置开始和结束时间
{
start=0; end=0;
}
}
四. 视图如下:
五.实验总结
通过这次实验, 我掌握了Java网络编程中对应的相关基础知识, 知道了ICMP协议以及跟踪运行Java网络包了解网络编程实现的细节问题, 并了解了Ping命令的功能。

我认识了ping 作为一种通信命令, 是IP协议的一部分, 利用他可以检查网络是否能够连通, 它也可以帮助我们分析网络故障。

通过这次实验,我掌握了Java网络编程中对应的相关基础知识,知道了ICMP 协议以及跟踪运行Java网络包了解网络编程实现的细节问题,并了解了Ping命令的功能。

我认识了ping作为一种通信命令,是IP协议的一部分,利用他可以检查网络是否能够连通,它也可以帮助我们分析网络故障。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

课程名称计算机网络实验序号实验五实验项目Ping程序的设计与实现2017年03月25 日实验报告要求1、实验报告封面填表说明(每份实验报告必须附上封面)(1)课程名称:要求与实验大纲和实验指导书中的课程名称一致。

(2)实验序号:指该课程的第几个实验。

(3)实验项目:要求与实验大纲和实验指导书中的实验项目一致。

(4)实验地点:填写完成该实验项目所在的实验室名称。

(5)实验学时:要求与实验大纲和实验指导书中完成该实验项目所需学时一致。

(6)实验类型:是指演示性、操作性、验证性、综合性、设计性。

演示性:教师操作,学生观察,验证理论、说明原理和方法。

操作性:学生按要求动手拆装、调试实验装置或上机操作,掌握其基本原理和方法。

验证性:按实验指导书(教材)要求,由学生通过操作验证所学理论,加深对理论、知识的理解,掌握基本实验知识、方法、技能、数据处理等。

综合性:实验内容涉及本课程的综合知识或相关课程的知识,运用多的知识、多种方法,按要求或自拟实验方案进行实验。

主要培养学生综合运用所学知识、实验方法和实验技能,以培养其分析、解决问题的能力。

设计性:给定实验目的、要求和实验条件,学生自己设计实验方案并加以实现的实验。

学生独立完成从查阅资料、拟定实验方案、实验方法和步骤(或系统分析和设计)、选择仪器设备(或自行设计缺制作)进行实验并完成实验全过程,形成实验报告,培养学生自主实验的能力。

(1)批改:全部批改及更正错误。

(2)评分:按百分制评分,不能评分为“优、良、中、差”或“A、B、C”。

(3)签名及批改日期:任课教师必须在每份学生实验报告中签名和写上批改日期。

(4)成绩:填写学生实验成绩表,实验成绩作为考试成绩评定的依据。

(4)评语:任课教师批改学生实验报告时,应给出简明扼要的评语。

二、实验原理与内容1、一种网络诊断工具2、发送ICMP回送请求报文3、接收ICMP回送应答报文4、IP报文格式5、WinSock原始套接字的使用方法与API函数W insock原始套接字编程过程中,服务器端/客户端的编程都按照以下步骤:初始化套接字(WSAStartup)创建套接字(socket或WSASocket)向服务器通信(sendto/recvfrom)关闭套接字(closesocket)结束使用套接字(WSACleanup)6、三种WinSock地址结构①用的Winsock地址结构sockaddr ,针对各种通信域的套接字,存储它们的地址信息。

②专门针对Internet 通信域的Winsock地址结构sockaddr_in③专用于存储IP地址的结构in_addr4.编写各个函数代码块5.编译,运行实验代码如下:(温馨提醒:意要在.cpp文件的前后添加#include"stdafx.h" (是预编译处理器把stdafx.h文件中的内容加载到程序中来。

))#include"stdafx.h"#pragma pack(4)#pragma comment( lib, "ws2_32.lib" )#include"winsock2.h"//#include "stdafx.h"//增加的头文#include"stdlib.h"#include"stdio.h"#define ICMP_ECHO 8 // ICMP ECHO 请求报文类型#define ICMP_ECHOREPLY 0 // ICMP ECHO 响应报文类型#define ICMP_MIN 8 // 最小ICMP报文大小为8 bytes (只有ICMP首部)#define ICMP_PACKET_SIZE 32 //ICMP报文数据大小#define ICMP_PACKET_NUMBER 4 //发送ICMP报文的个数#define MAX_PACKET 1024 // 最大ICMP报文数据长度#define ICMP_TIMEOUT1000 //ICMP超时时间#define xmalloc(s) HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,(s)) #define xfree(p) HeapFree (GetProcessHeap(),0,(p))/* 定义结构体:IP 首部*/typedef struct iphdr {unsigned int h_len : 4; // 首部长度unsigned int version : 4; // IP版本unsigned char tos; // 服务类型unsigned short total_len; // 报文总长度unsigned short ident; // IP报文标识符unsigned short frag_and_flags; // 分片标记和片偏移unsigned char ttl; // 生存时间unsigned char proto; // 报文数据的协议类型unsigned short checksum; // 首部检验和unsigned int sourceIP; // 源IPunsigned int destIP; // 目的IP}IpHeader;/* 定义结构体:ICMP 首部*/typedef struct icmphdr {BYTE i_type; // ICMP报文类型BYTE i_code; // 代码USHORT i_cksum; // 报文校验和USHORT i_id; // ICMP报文标识符USHORT i_seq; // 报文序号ULONG timestamp; //时间戳,不是ICMP报文首部的标准组成部分}IcmpHeader;void fill_icmp_data(char *, int); // ICMP请求报文填充函数USHORT checksum(USHORT *, int); // 校验和计算函数int decode_resp(char *, int, struct sockaddr_in *); // ICMP应答报文解析函数int main(int argc, char **argv){WSADATA wsaData; //套接字信息SOCKET sockRaw; //原始套件字char dest_ip[16];//目的IP(字符串)unsigned int addr = 0; //目的IP(整型)struct sockaddr_in dest; //目的IP(sockaddr_in结构)struct sockaddr_in from; //源socket地址int fromlen = sizeof(from);//源socket地址的长度int datasize; //报文总长度(=首部大小+数据大小)//int bwrote, bread; //实际发送和接收数据大小int timeout = ICMP_TIMEOUT; //超时时间USHORT seq_no = 0;//报文序号从0开始递增int statistic = 0; // 成功接收报文的个数char *icmp_data; //指向发送缓冲区的指针char *recvbuf; //指向接收缓冲区的指针memset(dest_ip, '\0', sizeof(dest_ip));if (argc<2) {printf("Please input destination host IP(请输入目的IP):");scanf("%s", &dest_ip);}elsememcpy(dest_ip, argv[1], strlen(argv[1]));/* 初始化函数*/if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0){//第一处printf("WSAStartup failed: %d\n", GetLastError());return -1;}/* 创建传输ICMP协议数据的原始套接字*/sockRaw = WSASocket(AF_INET, SOCK_RAW, IPPROTO_ICMP, NULL, 0, WSA_FLAG_OVERLAPPED);//第二/* raw-protocol interface */第三处if (sockRaw == INVALID_SOCKET) {printf("WSASocket() failed: %d\n", WSAGetLastError());return -1;}/* 设置套接字的接收超时选项(即设置SO_RCVTIMEO) */if (setsockopt(sockRaw, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout)) ==SOCKET_ERROR){printf("failed to set recv timeout: %d\n", WSAGetLastError());return -1;}/* 设置套接字的发送超时选项(即设置SO_SNDTIMEO) */if (setsockopt(sockRaw, SOL_SOCKET, SO_SNDTIMEO, (char*)&timeout, sizeof(timeout)) == SOCKET_ERROR){printf("failed to set send timeout: %d\n", WSAGetLastError());return -1;}/* 转换指定的目的IP为winsocket地址结构*/addr = inet_addr(dest_ip);//第四处inet_addr()的功能是将一个点分十进制的IP转换成一个长整数型数(u_long类型)dest.sin_addr.s_addr = addr;dest.sin_family = AF_INET;/* 创建发送缓冲区,分配内存*/datasize = ICMP_PACKET_SIZE + sizeof(IcmpHeader);icmp_data = (char*)xmalloc(MAX_PACKET);if (!icmp_data) {printf("HeapAlloc failed %d\n", GetLastError());return -1;}/* 创建接收缓冲区,分配内存*/recvbuf = (char*)xmalloc(MAX_PACKET);if (!recvbuf) {printf("HeapAlloc failed %d\n", GetLastError());return -1;}/* 填充待发送的ICMP请求报文*/memset(icmp_data, 0, MAX_PACKET);fill_icmp_data(icmp_data, datasize);/* 显示ping提示信息*/printf("\nPinging %s ....\n\n", dest_ip);/* 发送4个ICMP请求报文,并接收应答报文*/for (int i = 0; i<ICMP_PACKET_NUMBER; i++){int bwrote = 0, bread = 0; //实际发送和接收数据大小((IcmpHeader*)icmp_data)->i_cksum = 0; //校验和字段置0((IcmpHeader*)icmp_data)->timestamp = GetTickCount(); //时间戳字段置为当前系统时间((IcmpHeader*)icmp_data)->i_seq = seq_no++; //序号字段每次递增1((IcmpHeader*)icmp_data)->i_cksum = checksum((USHORT*)icmp_data, datasize);//计算校验和/* 发送ICMP请求报文*/bwrote = sendto(sockRaw, icmp_data, datasize, 0, (struct sockaddr*)&dest, sizeof(dest));//第五第六处if (bwrote == SOCKET_ERROR){if (WSAGetLastError() == WSAETIMEDOUT) {printf("Request timed out.\n");continue;}printf("sendto failed: %d\n", WSAGetLastError());return -1;}/* 接收ICMP应答报文*/bread = recvfrom(sockRaw, recvbuf, MAX_PACKET, 0, (struct sockaddr*)&from, &fromlen);//第七处if (bread == SOCKET_ERROR){if (WSAGetLastError() == WSAETIMEDOUT) {printf("Request timed out.\n");continue;}printf("recvfrom failed: %d\n", WSAGetLastError());return -1;}/* 如果解析成功,递增成功接收的数目++ */if (!decode_resp(recvbuf, bread, &from))statistic++;Sleep(1000); //间隔1000ms后再发下一个请求报文}/* 显示用户名和统计结果*/printf("\nPing statistics collected by XXX for %s \n", dest_ip);printf(" Packets: Sent = %d,Received = %d, Lost = %d (%2.0f%% loss)\n",ICMP_PACKET_NUMBER, //发送报文个数statistic,//接收报文个数(ICMP_PACKET_NUMBER - statistic),//丢失报文个数(float)(ICMP_PACKET_NUMBER - statistic) / ICMP_PACKET_NUMBER * 100);//丢包率/* 关闭套接字*/closesocket(sockRaw);//第九处/* 注销函数*/WSACleanup();return 0;/* ICMP回送请求报文填充函数*/void fill_icmp_data(char * icmp_data, int datasize){IcmpHeader *icmp_hdr;char *datapart;icmp_hdr = (IcmpHeader*)icmp_data;icmp_hdr->i_type = ICMP_ECHO;icmp_hdr->i_code = 0;icmp_hdr->i_id = (USHORT)GetCurrentProcessId();icmp_hdr->i_cksum = 0;icmp_hdr->i_seq = 0;datapart = icmp_data + sizeof(IcmpHeader);memset(datapart, 'E', datasize - sizeof(IcmpHeader));}/* ICMP回送应答报文解析函数*/int decode_resp(char *buf, int bytes, struct sockaddr_in *from){IpHeader *iphdr;IcmpHeader *icmphdr;unsigned short iphdrlen;iphdr = (IpHeader *)buf;iphdrlen = (iphdr->h_len) * 4;if (bytes < iphdrlen + ICMP_MIN) {printf("Too few bytes from %s\n", inet_ntoa(from->sin_addr));return -1;}icmphdr = (IcmpHeader*)(buf + iphdrlen);if (icmphdr->i_type != ICMP_ECHOREPLY) {printf("non-echo type %d recvd\n", icmphdr->i_type);return -1;}if (icmphdr->i_id != (USHORT)GetCurrentProcessId()) {printf("someone else''s packet!\n");return -1;}printf("%d bytes from %s:", bytes - iphdrlen - sizeof(IcmpHeader), inet_ntoa(from->sin_addr));printf(" icmp_seq = %d. ", icmphdr->i_seq);printf(" time: %d ms ", bytes);printf("\n");return 0;}/* 校验和计算函数*/USHORT checksum(USHORT *buffer, int size) {unsigned long cksum = 0;while (size >1) {cksum += *buffer++;size -= sizeof(USHORT);}if (size) {cksum += *(UCHAR*)buffer;}cksum = (cksum >> 16) + (cksum & 0xffff);cksum += (cksum >> 16);return (USHORT)(~cksum);}#include"stdafx.h"6.按Crtl+F5编译、运行,结果如图所示:。

相关文档
最新文档