课程设计---Ping程序设计与实现
Ping程序的设计与实现
Ping程序的设计与实现Ping的基本实现原理请参考以下文档:/view/e0769dc69ec3d5bbfd0a7476.html;/view/9ee3583143323968011c9213.html;初学者读代码请先百度:socket(),setsockopt(),HeapAlloc()等函数。
使用说明:1、找到\Debug\ping.exe (即生成的可执行文件的目录);(Ping是工程名)2、开始->运行->cmd进入命令提示符模式;3、cd \Debug\ping.exe;然后输入参数即可。
Ping程序源码(无注释)//Ping.h#define WIN32_LEAN_AND_MEAN#include<windows.h>#include<winsock2.h>#include<ws2tcpip.h>#include<stdio.h>#include<stdlib.h>typedef struct tagIP_HEADER{unsigned int h_len:4;unsigned int ver:4;unsigned char tos;unsigned short total_len;unsigned short ident;unsigned short frag_floags;unsigned char ttl;unsigned char protocol;unsigned short checksum;unsigned int sourceip;unsigned int destip;}IP_HEADER,*PIP_HEADER;typedef struct tagIP_OPT_HEADER{unsigned char code;unsigned char len;unsigned char ptr;unsigned long addr[9];}IP_OPT_HEADER,*PIP_OPT_HEADER;typedef struct tagICMP_HEADER{unsigned char type;unsigned char code;unsigned short checksum;unsigned short id;unsigned short seq;unsigned long timestamp;}ICMP_HEADER,*PICMP_HEADER;#define DEF_PACKET_SIZE 32#define MAX_PACKET_SIZE 1024#define ICMP_ECHO 8#define ICMP_ECHOREPL Y 0#define IP_RECORD_ROUTER 7void usageinfo(char *progname);void FillIcmpData(char *icmp_data,int size);USHORT CheckSum(USHORT *buf,int size);void DecodeIcmpHeader(char *buf,int ret,LPSOCKADDR_IN lpSin); void DecodeIpHeader(char *buf,int bytes);//Ping.cpp#include<stdio.h>#include"Ping.h"#pragma comment(lib,"ws2_32")int main(int argc,char *argv[]){if(argc==1){usageinfo(argv[0]);return -1;}BOOL bRecordRout =FALSE;SOCKET hSocket =INV ALID_SOCKET;SOCKADDR_IN dstSin;SOCKADDR_IN fromSin;IP_OPT_HEADER ipOptHeader;char* pIcmpData = NULL;char* pRecvData = NULL;char* lpDstIp =NULL;int datasize =DEF_PACKET_SIZE;int ret;int rcvNum;for(int i=1;i<argc;i++){if(strchr(argv[i],'-')){switch(tolower(argv[i][1])){case 'r':bRecordRout=TRUE;break;case 'd':datasize=atoi(argv[i+1]);i=argc+1;break;}}else if(strchr(argv[i],'.')){int l=strlen(argv[i]);if(l<7||l>15)usageinfo(argv[0]);elselpDstIp=argv[i];}}WSADATA wsaData;WORD wVer=MAKEWORD(2,2);if(WSAStartup(wVer,&wsaData)!=0){printf("WSAStartup Error!\n");return -1;}hSocket=WSASocket(AF_INET,SOCK_RAW,IPPROTO_ICMP,NULL,0,WSA_FLAG_OVERLAPPED);if(hSocket==INV ALID_SOCKET){printf("WSASocket Error,Code:%d",WSAGetLastError());WSACleanup();return -1;}if(bRecordRout){ZeroMemory(&ipOptHeader,sizeof(ipOptHeader));ipOptHeader.code=IP_RECORD_ROUTER;ipOptHeader.len=39;ipOptHeader.ptr=4;if((ret=setsockopt(hSocket,IPPROTO_IP,IP_OPTIONS,(char*)&ipOptHeader,sizeof(ipOptH eader)))==SOCKET_ERROR){printf("setsockopt(IP_OPTIONS)error,code:%d",WSAGetLastError());WSACleanup();closesocket(hSocket);return -1;}}int timeout=1000;if((ret=setsockopt(hSocket,SOL_SOCKET,SO_RCVTIMEO,(char*)&timeout,sizeof(timeout )))==SOCKET_ERROR){printf("setsockopt(SO_RCVTIMEO)error,code:%d",WSAGetLastError());WSACleanup();closesocket(hSocket);return -1;}if((ret=setsockopt(hSocket,SOL_SOCKET,SO_SNDTIMEO,(char*)&timeout,sizeof(timeout )))==SOCKET_ERROR){printf("setsockopt(SO_SNDTIMEO)error,code:%d",WSAGetLastError());WSACleanup();return -1;}pIcmpData=(char*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,MAX_PACKET _SIZE);pRecvData=(char*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,MAX_PACKET _SIZE);if(pIcmpData==NULL||pRecvData==NULL){printf("HeapAlloc Error\n");WSACleanup();return -1;}datasize+=sizeof(ICMP_HEADER);ZeroMemory(&dstSin,sizeof(dstSin));dstSin.sin_family=AF_INET;dstSin.sin_addr.s_addr =inet_addr(lpDstIp);FillIcmpData(pIcmpData,datasize);printf("Ping %s with %d bytes of data\n",inet_ntoa(dstSin.sin_addr),datasize);int count=0;int seq=0;rcvNum=0;while(1){count++;if(count==5)break;((PICMP_HEADER)pIcmpData)->checksum=0;((PICMP_HEADER)pIcmpData)->seq=seq++;((PICMP_HEADER)pIcmpData)->timestamp=GetTickCount();((PICMP_HEADER)pIcmpData)->checksum=CheckSum((USHORT*)pIcmpData,datasize);if((ret=sendto(hSocket,pIcmpData,datasize,0,(LPSOCKADDR)&dstSin,sizeof(dstSin)))==S OCKET_ERROR){if(WSAGetLastError()==WSAETIMEDOUT){printf("time out.\n");continue;}else{printf("sendto error,code:%d",WSAGetLastError());closesocket(hSocket);WSACleanup();return -1;}}int fromLen=sizeof(fromSin);if((ret=recvfrom(hSocket,pRecvData,MAX_PACKET_SIZE,0,(sockaddr*)&fromSin,&from Len))==SOCKET_ERROR){if(WSAGetLastError()==WSAETIMEDOUT){printf("time out.\n");continue;}printf("recvform fail!\n");closesocket(hSocket);WSACleanup();return -1;}rcvNum++;DecodeIcmpHeader(pRecvData,ret,&fromSin);}printf("\n Ping Statistics for :%s\n",lpDstIp);printf("\t Send=%d Received=%d,Lost=%d(%d%%loss)",4,rcvNum,4-rcvNum,(4-rcvNum)/4*100);if(hSocket!=INV ALID_SOCKET)closesocket(hSocket);HeapFree(GetProcessHeap(),0,pIcmpData);HeapFree(GetProcessHeap(),0,pRecvData);WSACleanup();return 0;}void usageinfo(char *progname){printf("Pingtool,byblode(********************.cn\n)");printf("usage:ping[-r]<host ip>[-d][data size]\n");printf("\t-r:\trecord router\n");printf("\thost ip:\thost ip to ping\n");printf("\t-d:\tuse data size option\n");printf("\tdata size:\tdata size to ping(<=1024)\n");}void FillIcmpData(char *icmp_data,int size){ICMP_HEADER *icmpHdr;icmpHdr=(PICMP_HEADER)icmp_data;icmpHdr->checksum=0;icmpHdr->code=0;icmpHdr->id=(unsigned short)GetCurrentProcessId();icmpHdr->seq=0;icmpHdr->type=ICMP_ECHO;icmpHdr->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);}void DecodeIcmpHeader(char *buf,int ret,LPSOCKADDR_IN lpSin) {ICMP_HEADER *icmpHdr;IP_HEADER *ipHdr;int ipHdrLen;static int first=0;DWORD tick=GetTickCount();ipHdr=(IP_HEADER*)buf;ipHdrLen=ipHdr->h_len*4;if(ipHdrLen==60&&!first)DecodeIpHeader(buf,ret);icmpHdr=(ICMP_HEADER *)(buf+ipHdrLen);if(icmpHdr->type!=ICMP_ECHOREPL Y){printf("no echo reply %d recved\n",icmpHdr->type);return ;}if(icmpHdr->id!=(USHORT)GetCurrentProcessId()){printf("someone else's packet!\n");return;}printf("Reply form: %s",inet_ntoa(lpSin->sin_addr));printf("\tbytes: %d icmp seq: %d TTL=128",ret,icmpHdr->seq);printf("time: %dms\n",tick-icmpHdr->timestamp);first++;return;}void DecodeIpHeader(char *buf,int bytes){IP_OPT_HEADER *ipOptHdr;IN_ADDR in;ipOptHdr=(IP_OPT_HEADER *)(buf+20);printf("Record Router:");for(int i=0;i<(ipOptHdr->ptr/4)-1;i++){in.S_un.S_addr=ipOptHdr->addr[i];printf("\t%-15s\n",inet_ntoa(in));}}。
计算机网络课程设计(ping)
计算机网络课程设计Ping程序设计(后附源码)四川大学黄昊1143041195一.设计目标二.ICMP包结构三.校验和计算四.代码实现a)ICMP封包b)ICMP包转换成字节数组c)域名解析、选择IPv4地址d)原始套接口e)计算校验和五.运行结果六.总结一、设计目标本程序设计实现基本的ping程序功能,包括域名解析,ICMPv4回显包发送,统计丢失率等功能。
二、ICMP包结构ICMP包包含在IP包结构之内,是去除IP包头的部分,C#提供的Raw Socket功能可以实现包装ICMP结构,但自动包含IP包头等结构。
ICMP包由1Byte类型、1Byte SubCode、2字节校验和、2字节标示符、2字节序号,若干字节数据组成。
其结构图如下:4Byte类型号8 、子代码表示ICMP回显功能,默认标示符45、序号0、Data小节可填充数据,本程序填充了ASCII码‘a’十六进制61,填充24字节,所以整个包大小共32字节。
三、校验和计算对于ICMP包中的校验和,首先将校验和填0之后再整体计算。
计算时,按照2字节为一个单位累加,最后将所有溢出结果再次做加法,最后整体取反,返回一个2字节长的校验和。
具体计算方法伪代码如下:Int32 cksum = 0;for (int i = 0; i < 16; i++){cksum += ConvertToUInt16(packet, i * 2);}cksum = (cksum >> 16) + (cksum & 0xffff);cksum += (cksum >> 16);return (ushort)(~cksum);四、代码实现a)实现难度1:封装ICMP包。
为了方便操作与计算,在C#中,创建了一个ICMP包的结构体。
为了使包的逻辑结构与实际发送的结构一样,借助了C#提供的一个机制,叫非托管内存布局,使用StructLayoutAttribute属性,其中参数LayoutKind.Sequential指定了整个结构体的数据堆放方式为顺序堆放,保证内存中数据的连续性。
计算机网络基础课程设计Ping程序实现
计算机网络基础课程设计Ping程序实现计算机网络工程课程设计报告题目:Ping程序的实现学生姓名:学号:专业班级:计科专业班同组姓名: 指导教师:设计时间:2022年下学期第某周指导老师意见:评定成绩:签名:日期:年月日目录一、课程设计的目的和意义2二、课程设计的内容和要求21.内容:22.要求:2三、课程设计的相关技术2四、课程设计过程21.Ping主模块22.功能控制模块43.数据报解析模块5五、课程设计小结6六、参考文献7七、附录(程序清单)7八、心得体会11一、课程设计的目的和意义利用ICMP数据包、C语言实现Ping命令程序,能实现基本的Ping操作,发送ICMP回显请求报文,用于测试—个主机到只一个主机之间的连通情况。
通过本程序的训练,使学生熟悉ICMP报文结构,使学生对ICMP有更深的理解,掌握Ping程序的设计方法,掌握网络编程的方法和技巧,从而编写出功能更强大的程序。
二、课程设计的内容和要求1.内容:用C语言实现Ping命令程序,能实现基本的Ping操作,发送ICMP回显请求报文,用于测试—个主机到只一个主机之间的连通情况。
2.要求:1)独立完成程序的设计、编码和调试。
2)系统利用C语言实现,程序调试环境为TurboC或VC;3)按照课程设计规范书写课程设计报告。
4)采用VC环境进行调试运行。
三、课程设计的相关技术由于Ping程序是面向用户的应用程序,该程序使用ICMP的封装机制,通过IP协议来工作。
为了实现直接对IP和ICMP包进行操作,实验中使用RAW模式的ocket编程。
首先定义IP数据报首部,在IP数据报的基础上定义ICMP数据报首部,并初始化一些全局变量。
接着自定义填充ICMP数据报字段函数FillICMPData()、校验和函数checkum()、解读ICMP报首部函数DecodeICMPHeader()、释放资源函Cleanup()。
最后主函数通过调用这些函数来实现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命令的设计与实现》专业班级计科094 同组人姓名同组人学号实验日期2013-04-10 指导教师成绩2013 年 04 月 10 日设计目的和要求1、实验目的:Ping命令向目的主机发送ICMP ECHO—REQUEST请求并接收目的主机返回的响应报文,用来检验本地主机和远程的主机是否连接。
2.实验要求:利用ICMP数据包,测试主机的连通性,通过课程设计,使学生熟悉ICMP报文结构,使学生对ICMP有更深的理解。
要求:输出参考系统自带ping程序,命令行运行:ping ip二、设计说明设计分析:使用原始套接字可以读写ICMP分组,利用原始套接字发送ICMP回显请求,并接收ICMP 回显应答,通过icmp_send()发送ICMP回显示请求包,icmp_recv()接收ping目的主机的回复,并使用终端信号处理函数SIGINT处理信号,建立两个线程,一个用于发送数据,另一个用于接收响应数据,主程序等待两个线程运行完毕后再进行下一步动作。
最后,主程序讲发送数据和接收的数据进行统计,并将结果打印出来。
系统运行环境:虚拟机:Fedora14(linux操作系统) gcc设计中的重点和难点:ICMP数据包的打包和解包,以及从CRC16校验算法的分析实现输入和输出条件:在linux系统下运行ping 在出现4个响应包后按Ctrl+c键停止发送。
三、系统详细设计《Ping命令的设计与实现》Ping命令向目的主机发送ICMP ECHO—REQUEST请求并接收目的主机返回的响应报文,用来检验本地主机和远程的主机是否连接。
协议格式图1.1中已经对ICMP协议的报文格式进行了说明。
Ping 的客户端方式的类型为8,代码值为0,表示ICMP的回显请求。
类型为0,代码为0是,是ICMP回显应答。
检验和为16为的crc16 的算法。
0 7 8 15 16 31图1.1 ICMP报文的数据格式图1.2所示为ping所使用的类型和代码格式。
ping程序的设计与实现
ping程序的设计与实现
Ping程序的设计与实现是通过一种单向测量技术来实现的,它可以用来评估网络的性能、访问故障和网络可用性。
Ping程序工作时会首先向目标主机发送一个ICMP(网际控制报文协议)报文,然后等待目标主机的应答。
在实现ping程序的过程中,首先要为发送的ICMP数据报定义一个数据结构,这个数据结构将包含所有必要的信息,如报文类型、报文代码、校验和等。
其次,要实现函数,对这个数据结构进行填充和序列化,以便将ICMP报文发送出去。
实现发送ICMP报文后,就要开始接收应答。
为此,可以利用Socket API来创建一个Raw Socket,以便从网络上接收ICMP报文,并将其解码为数据结构,以便能够识别是哪一条报文的应答。
最后,还需要实现超时,用来处理因网络拥塞或丢包等原因导致的应答报文没有收到的情况。
这可以通过在发送ICMP报文之前先设置一个定时器,当定时器到期时,就可以判断该报文没有收到应答报文而超时。
以上就是ping程序的大致设计与实现方式,整个实现的过程可以大体分为发送ICMP数据报、接收应答和超时处理三部分。
这些都需要对数据报结构进行定义和填充,以及使用Socket API创建Raw Socket 来发送和接收数据,并通过设置定时器来实现超时处理,以保证ping 程序可以正常工作。
计算机网络课程设计
成绩:课程设计报告设计名称:计算机网络课程设计设计项目:基于ICMP协议的ping命令设计与实现姓名:孙泽宇专业:计算机科学与技术学院班级:计算机14-5班学号:1404010522计算机科学与技术学院2016年12月23 日目录一、课程设计的目的和意义PING程序是我们使用的比较多的用于测试网络连通性的程序。
PING程序基于ICMP,使用ICMP的回送请求和回送应答来工作。
由计算机网络课程知道,ICMP 是基于IP的一个协议,ICMP包通过IP的封装之后传递。
二、课程设计的内容和要求PING程序是用于测试网络连通性的程序。
要求在WINDOWS环境下实现基本的PING 程序功能. 在命令提示符下输入: PING ***.***.***.*** 其中***为目的主机的IP地址,不要求支持域名,对是否带有开关变量也不做要求。
不带开关变量时,要求返回4次响应。
返回信息的格式 REPLY FROM ***.***.***.*** 或TimeOut (无法PING通的情况)三、设计用设备仪器1.pc机2.Myeclipse软件四、课程设计的相关技术ping 程序是用来探测主机到主机之间是否可通信,如果不能ping到某台主机,表明不能和这台主机建立连接。
ping 使用的是ICMP协议,它发送ICMP回送请求消息给目的主机。
ICMP协议规定:目的主机必须返回ICMP回送应答消息给源主机。
如果源主机在一定时间内收到应答,则认为主机可达。
ICMP协议通过IP协议发送的,IP协议是一种无连接的,不可靠的数据包协议。
因此,保证数据送达的工作应该由其他的模块来完成。
其中一个重要的模块就是ICMP(网络控制报文)协议。
当传送IP数据包发生错误--比如主机不可达,路由不可达等等,ICMP协议将会把错误信息封包,然后传送回给主机。
给主机一个处理错误的机会,这也就是为什么说建立在IP层以上的协议是可能做到安全的原因。
ICMP 数据包由8bit的错误类型和8bit的代码和16bit的校验和组成。
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程序的设计与实现:系别:计算机与信息工程学院专业:计算科学与技术组别:第五小组~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程序的设计与实现系别:计算机与信息工程学院专业:计算科学与技术组别:第五小组起止日期: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。
dev c++实现ping程序的设计与实现
要实现一个ping程序,首先需要了解ping程序的基本工作原理。
ping程序通过向目标主机发送ICMP Echo请求并等待回应来检测网络连接。
以下是使用C语言实现一个简单的ping程序的步骤:1. 包含必要的头文件。
2. 定义一些常量和变量。
3. 编写一个函数,用于发送ICMP Echo请求。
4. 编写一个函数,用于接收ICMP Echo回应。
5. 编写主函数,解析命令行参数,调用上述函数进行ping操作。
以下是一个简单的C语言实现的ping程序示例:```c#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <arpa/inet.h>#include <netinet/ip.h>#include <sys/socket.h>#include <netinet/icmp.h>#include <netdb.h>#define MAX_PACKET_SIZE 65507#define TIMEOUT 5void send_icmp_request(int sockfd, struct sockaddr_in *dest_addr);void receive_icmp_response(int sockfd);int main(int argc, char *argv[]) {if (argc != 2) {printf("Usage: %s <hostname>", argv[0]);return 1;}struct hostent *host = gethostbyname(argv[1]);if (host == NULL) {perror("gethostbyname");return 1;}struct sockaddr_in dest_addr;memset(&dest_addr, 0, sizeof(dest_addr));dest_addr.sin_family = AF_INET;dest_addr.sin_port = htons(80);memcpy(&dest_addr.sin_addr, host->h_addr, host->h_length);int sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);if (sockfd < 0) {perror("socket");return 1;}setsockopt(sockfd, IPPROTO_IP, IP_TTL, &TIMEOUT, sizeof(TIMEOUT));send_icmp_request(sockfd, &dest_addr);receive_icmp_response(sockfd);close(sockfd);return 0;}void send_icmp_request(int sockfd, struct sockaddr_in *dest_addr) { char packet[MAX_PACKET_SIZE];struct icmphdr *icmp_header = (struct icmphdr *)packet;memset(packet, 0, sizeof(packet));icmp_header->type = ICMP_ECHO;icmp_header->code = 0;icmp_header->checksum = 0;icmp_header->un.echo.id = htons(getpid());icmp_header->un.echo.sequence = htons(1);icmp_header->un.echo.data[0] = 'A';icmp_header->un.echo.data[1] = 'B';icmp_header->un.echo.data[2] = 'C';icmp_header->un.echo.data[3] = 'D';icmp_header->un.echo.data[4] = 'E';icmp_header->un.echo.data[5] = 'F';icmp_header->un.echo.data[6] = 'G';icmp_header->un.echo.data[7] = 'H';icmp_header->un.echo.data[8] = 'I';icmp_header->un.echo.data[9] = 'J';icmp_header->un.echo.data[10] = 'K';icmp_header->un.echo.data[11] = 'L';icmp_header->un.echo.data[12] = 'M';icmp_header->un.echo.data[13] = 'N';icmp_header->un.echo.data[14] = 'O';icmp_header->un.echo.data[15] = 'P';icmp_header->checksum = checksum(packet, sizeof(packet));sendto(sockfd, packet, sizeof(packet), 0, (struct sockaddr *)dest_addr, sizeof(*dest_addr));}void receive_icmp_response(int sockfd) {char buffer[MAX_PACKET_SIZE];struct icmphdr *icmp_header;struct sockaddr_in src_addr;socklen_t src_addr_len = sizeof(src_addr);int recv_len = recvfrom(sockfd, buffer, sizeof(buffer), 0, (struct sockaddr *)&src_addr, &src_addr_len);if (recv_len < 0) {perror("recvfrom");return;}icmp_header = (struct icmphdr *)buffer;if (icmp_header->type == ICMP_ECHOREPLY) {printf("Received ICMP echo reply from %s:%d", inet_ntoa(src_addr.sin_addr), ntohs(src_addr.sin_port));printf("Round trip time: %ld ms", (long)((unsigned long)recv_len * 8 / 1000));} else {printf("Received unexpected ICMP message type: %d", icmp_header->type);}}unsigned short checksum(const void *buffer, int length) {unsigned long sum = 0;const unsigned short *shorts = (const unsigned short *)buffer;while (length > 1) {sum += *shorts++;length -= 2;}if (length == 1) {sum += htons(*(unsigned char *)buffer << 8);} else {sum += htons(*(unsigned short *)buffer);}while (sum >> 16) {sum = (sum & 0xFFFF) + (sum >> 16);}return ~sum;}```这个程序首先解析命令行参数,获取目标主机名。
5-Ping程序设计与实现
4.构造IP、ICMP数据报;
接收ICMP差错报文并进行解析处理;8小时
5.课程设计报告4小时
计算机网络课程设计任务书
设计题目
Ping程序设计与实现(Java)★
已知技术参数和设计要求
1.已知参数:目的节点IP地址或主机名
2.设计要求:通过原始套接字编程,模拟Ping命令,实现其基本功能,即输入一个IP地址或一段IP地址的范围,分别测试其中每个IP地址所对应主机的可达性,并返回耗时、生存时间等参数,并统计成功发送和回送的Ping报文。
2.1初始化Windows Sockets网络环境;
2.2解析命令行参数,构造目的端socket地址;
2.3定义IP、ICMP报文;
2.4接收ICMP差错报文并进行解析。
3.程序实现主要用到Java网络包中的类Ine悉原始socket相关知识;
2.熟悉Ping的实现原理和ICMP协议及报文格式;
3.Windows Sockets网络环境的初始化,解析命令行;
4.创建原始套接字;
5.构造IP、ICMP数据报;
6.接收ICMP差错报文并进行解析处理;
7.课程设计任务说明书。
设计工作计划与进度安排
1.知识准备,整体思路设计2小时
2.开发环境与程序调试环境4小时
3. Windows Sockets网络环境的初始化,
计算机网络实验之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程序指导教师姓名:起止日期:一、选题背景(标题:四号仿宋加粗,顶格,行间距: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-4 3.ping:图1-5 4。
main()函数:图1—6三、详细设计要实现ping程序,需要实现以下步骤:1.初始化//定义IP首部格式typedef struct _IPHeader{u_char VIHL;//版本和首部长度u_char ToS;//服务类型u_short TotalLen;//总长度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 Type;//类型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 _ECHOREPLY{IPHDR ipHdr;ECHOREQUEST echoRequest;char cFiller[256];}ECHOREPLY, *PECHOREPLY;2.功能//计算校验和函数u_short checksum(u_short *buffer, int len) //发送回应请求函数int SendEchoRequest(SOCKET s, struct sockaddr_in *lpstToAddr)//接收应答回复并进行解析函数DWORD RecvEchoReply(SOCKET s, LPSOCKADDR_IN lpsaFrom,u_char *pTTL)3。
ping程序的设计实现分析范文教案资料
p i n g程序的设计实现分析范文滁州学院课程设计报告课程名称:计算机网络课程设计设计题目: 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程序的设计与实现专业班级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协议的一部分,利用他可以检查网络是否能够连通,它也可以帮助我们分析网络故障。
ping的实现课程设计
ping的实现 课程设计一、课程目标知识目标:1. 理解ping命令的基本工作原理,掌握其网络诊断功能;2. 学习并掌握使用ping命令检测网络连通性的方法;3. 了解ping命令的参数设置及其作用。
技能目标:1. 学会运用ping命令进行简单的网络故障排查;2. 能够通过ping命令的结果,分析网络延迟、丢包等问题;3. 培养学生对网络故障的敏感度,提高解决问题的能力。
情感态度价值观目标:1. 培养学生对计算机网络知识的兴趣,激发探索精神;2. 培养学生团队合作意识,学会在网络环境中与他人共同解决问题;3. 强化网络安全意识,让学生明白网络诊断工具的正确使用方法。
课程性质:本课程为计算机网络基础课程,旨在帮助学生掌握网络诊断的基本方法,提高实际操作能力。
学生特点:学生为初中年级,对计算机网络知识有一定的了解,具备基本的计算机操作能力。
教学要求:通过本章节的学习,要求学生能够熟练运用ping命令进行网络诊断,并具备一定的网络故障排查能力。
将目标分解为具体的学习成果,以便后续的教学设计和评估。
二、教学内容1. 理论知识:- 计算机网络基础知识回顾,重点强调TCP/IP协议;- ping命令的工作原理,介绍ICMP协议的作用;- ping命令的参数及其功能解释,如:-t、-a、-n、-l等。
2. 实践操作:- 演示如何使用ping命令检测网络连通性;- 指导学生使用ping命令检测本地网络中的设备;- 实践案例:分析ping命令返回结果,判断网络延迟、丢包等问题。
3. 教学大纲:- 第一课时:计算机网络知识回顾,介绍ping命令及其工作原理;- 第二课时:ping命令的参数介绍,演示如何使用ping命令;- 第三课时:实践操作,学生分组进行网络诊断,分析ping命令结果;- 第四课时:总结与拓展,讨论网络故障排查的其他方法,强化网络安全意识。
教材关联:教学内容与课本第三章“网络诊断与故障排除”相关,结合课本案例,使学生更好地掌握网络诊断技巧。
ping的简单实现课程设计
ping的简单实现课程设计一、教学目标本课程的教学目标是使学生掌握ping命令的基本使用方法,理解其工作原理,能够通过ping命令诊断网络连接问题。
具体包括:1.了解ping命令的作用和基本语法。
2.掌握如何使用ping命令检测网络连接。
3.理解ping命令的响应结果的含义。
4.能够独立操作计算机,运行ping命令。
5.能够分析ping命令的输出结果,判断网络连接状态。
6.能够根据实际情况,选择合适的ping命令参数。
情感态度价值观目标:1.培养学生对网络通信技术的兴趣和好奇心。
2.培养学生解决问题的能力和团队合作精神。
二、教学内容本课程的教学内容主要包括以下几个部分:1.ping命令的基本概念和语法。
2.ping命令的使用方法,包括如何检测网络连接。
3.ping命令的响应结果的解读。
4.如何在实际情况下,选择合适的ping命令参数。
三、教学方法本课程的教学方法包括:1.讲授法:讲解ping命令的基本概念、语法和原理。
2.实验法:引导学生实际操作ping命令,检测网络连接。
3.讨论法:分组讨论ping命令的输出结果,培养学生解决问题的能力。
四、教学资源本课程的教学资源包括:1.教材:《计算机网络基础》相关章节。
2.多媒体资料:PPT课件,网络连接检测的实验视频。
3.实验设备:计算机、网络环境。
以上是本课程的教学设计,希望能够帮助学生更好地掌握ping命令的使用,提高网络故障排除的能力。
五、教学评估本课程的教学评估将采用多元化的评估方式,以全面、客观、公正地评价学生的学习成果。
评估方式包括:1.平时表现:通过观察学生在课堂上的参与度、提问回答、小组讨论等表现,评估学生的学习态度和理解能力。
2.作业:布置相关的ping命令练习题,要求学生独立完成,通过作业的质量和完成时间评估学生的掌握程度。
3.实验报告:学生在实验过程中,需要撰写实验报告,描述实验过程、结果和收获,通过实验报告评估学生的实际操作能力和问题解决能力。
计算机网络实验之Ping程序的设计与实现
计算机网络实验之Ping程序的设计与实现课程名称计算机网络实验序号实验五实验项目 Ping程序的设计与实现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 ,针对各种通信域的套接字,存储它们的地址信息。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
课程设计课程名称____计算机网络_____题目名称_Ping程序设计与实现学生学院____计算机学院____专业班级____08计科4班___学号_______2011年 1 月8 日一、课程设计目的本次课程设计的目的旨在通过网络相关程序的编写,使我们能深入理解TCP/IP协议机制,以及初步掌握基于Winsocket的网络编程技术。
同时巩固相关的理论知识,为以后程序开发打下良好而又坚实的基础。
二、知识准备1、ICMP协议互联网控制信息协议(Internet CONTROL Message Protocol),用于错误报告和调试。
该协议是TCP/IP协议集中的一个子协议,属于网络层协议,主要用于在主机与路由器之间传递控制信息,包括报告错误、交换受限控制和状态信息等。
当遇到IP数据无法访问目标、IP路由器无法按当前的传输速率转发数据包等情况时,会自动发送ICMP消息。
我们可以通过Ping命令发送ICMP回应请求消息并记录收到ICMP回应回复消息,通过这些消息来对网络或主机的故障提供参考依据。
常见ICMP报文有响应请求报文,目标不可到达、源抑制和超时报文,此外还有时间戳报文。
2、Ping工作原理Ping的原理就是首先建立通道,然后发送包,对方接受后返回信息,这个包至少包括以下内容:发送的时候,包的内容包括对方的ip地址和自己的地址,还有序列数;回送的时候包括双方地址,还有时间等,主要是接受方在都是在操作系统内核里做好的,时刻在监听。
Ping程序生成一个icmp“回送请求”,将其发送给目的主机。
通过检测是否可以收到目标主机的应答,便可以知道网络的连通性。
(3) Tracert 工作原理透过向目标发送不同 IP 生存时间 (TTL) 值的ICMP回应数据包,Tracert 诊断程序确定到目标所采取的路由。
要求路径上的每个路由器在转发数据包之前至少将数据包上的 TTL 递减 1。
数据包上的 TTL 减为 0 时,路由器应该将“ICMP已超时”的消息发回源系统。
Tracert 先发送 TTL 为 1 的响应数据包,并在随后的每次发送过程将 TTL 递增1,直到目标响应或 TTL 达到最大值,从而确定路由。
透过检查中间路由器发回的“ICMP已超时”的消息确定路由。
三、界面设计及数据结构的说明1 、MFC界面设计建立流程步骤一:打开VC6.0,点击文件选项,在project选项卡中选择MFC Appwizard(exe),项目名称为ping。
步骤二:在新窗口中选择窗口类型为基于对话框的类型。
步骤三:设置界面选项步骤四:设置窗口类型步骤五:选择相应类,点击finish完成。
界面建立成功后添加相应按钮及功能模块。
主界面设计如下:2、数据结构的定义及说明(1)定义IP头部typedef struct _IpHeader{unsigned int HeaderLength:4; // 头部长度unsigned int Version:4; // IP版本号unsigned char TypeOfService; // 服务类型unsigned short TotalLength; // 收发包的总长度unsigned short Identification; // 唯一校验符unsigned short FragmentationFlags; // 标志位unsigned char TTL; // 生存时间unsigned char Protocol; // 协议类型 (TCP, UDP 等)unsigned short CheckSum; // IP头部校验和unsigned int sourceIPAddress; // 源地址unsigned int destIPAddress; // 目的地址} IpHeader;(2)定义ICMP头部typedef struct _IcmpHeader{BYTE IcmpType; //icmp类型BYTE IcmpCode; //编码类型USHORT IcmpChecksum; //icmp校验和USHORT IcmpId;USHORT IcmpSeq; //icmp序列号ULONG IcmpTimestamp; // 头部无标准定义,但仍需保留} IcmpHeader;(3)CIcmp类class CIcmp : public CSocket{public:BOOL OpenNewSocket(HWND hWnd, unsigned int NotificationMessage, long NotifyEvents);BOOL OpenNewSocket(HWND hWnd, unsigned int NotificationMessage, long NotifyEvents, int AFamily, int AType, int AProtocol);int CloseIcmpSocket(void);BOOL Connect(int ReceiveTimeout, int SendTimeout);BOOL Connect(LPINT ReceiveTimeout, LPINT SendTimeout, int AFamily, int AType, int AProtocol);int SetTTL(int TTL);int SetAsynchNotification(HWND hWnd, unsigned int Message, long Events);int Receive(LPSTR pIcmpBuffer, int IcmpBufferSize);unsigned long GetIPAddress (LPSTR iHostName);int Ping (LPSTR pIcmpBuffer, int IcmpBufferSize);unsigned short IcmpChecksum(unsigned short FAR *lpBuf, int Len);void DisplayError(CString ErrorType, CString FunctionName);public:CIcmp(void);CIcmp(CIcmp ©);~CIcmp(void);private:public:LPIcmpHeader pIcmpHeader;LPIpHeader pIpHeader;SOCKET icmpSocket;SOCKADDR_IN icmpSockAddr;SOCKADDR_IN rcvSockAddr;DWORD icmpRoundTripTime;DWORD icmpPingSentAt;DWORD icmpPingReceivedAt;int icmpRcvLen;int icmpHops;int icmpMaxHops;int icmpCurSeq;int icmpCurId;int icmpPingTimer;int icmpSocketError;int icmpSocketErrorMod;unsigned long icmpHostAddress;protected:};typedef CIcmp FAR * LPIcmp;(4)CPingPlusDlg类class CPingPlusDlg : public CDialog{enum ImageType{Icon_Blank,Icon_BlueArrow};private:void StopTimer();void StartTimer();void ChangeIconState(void);BOOL InitSockets();BOOL FetchWinsockSettings();BOOL LoadRegValues(void);void SaveRegValues();void SendPing(void);unsigned long HostIPAddress();void UpdateTrace ();void DisplayTrace(LPCSTR TripTimeMessage, LPCSTR IPAddressMessage, LPCSTR HostMessage); void EndTrace(void);void InitImageList();int AddListColumn(int column, int lfmt, int lmaxwidth, LPSTR ltext, int lsubitem);void DisplayBlankLine(void);void SetTraceSequence(int Seq, int FocusItem, ImageType FocusImage);void SetTraceFocus(int FocusItem, int FocusSubItem);void SetDisplayImage(int FocusItem, enum ImageType FocusImage);void TraceComment(CString Comment);public:CPingPlusDlg(CWnd* pParent = NULL); // 标准构造器protected:HICON m_hIcon;LRESULT OnPINGAsynch(WPARAM wParam, LPARAM lParam);public:CIcmp PingSocket; // Icmp 对象WSADATA wsaData; // Windows Socket 信息结构CString LocalNameServer;CString LocalDomainName; // 域名 (从注册机构获取)CString DefHost; // 默认主机名 (从注册机构获取)char HostName[MAXHOSTNAME]; // 将主机名加入到会话中去char CurrentHostName[MAXHOSTNAME]; // 当前正在ping的主机struct in_addr TraceTarget; // 操作路径终端BOOL TimerActive; // TRUE = 计时器到时unsigned long icmpIntervalCount; // 当前计时时间间距unsigned long icmpMaxIntervals; // 最大间距char icmpBuffer[MAX_PACKET]; // icmp操作的普通缓冲区LPSTR pIcmpBuffer; // icmp缓冲区的故障分析报告指向int icmpDataLen; // icmp发出信息的字节数 (不计算头部)int icmpPingTTL; // 路径操作所用到的ttl值BOOL icmpTracing;// TRUE = 路径操作, FALSE = PING操作BOOL PingSent; // TRUE = 等待ECHO回复, FALSE = 忽略输入};四、程序主题功能设计模块1、调用ping模块void CPingPlusDlg::OnPingButton(){IconState = 0;DisplayBlankLine ();icmpTracing = FALSE;icmpPingTTL = PingSocket.icmpMaxHops; //ping生存时间为最大icmp跳数PingSocket.icmpCurSeq = 0;//当前icmp序列为0SendPing ( );//开始执行ping}2、初始化socketBOOL CPingPlusDlg::InitSockets(){if (!PingSocket.OpenNewSocket(GetSafeHwnd(),WSA_PING_ASYNC,FD_READ | FD_WRITE,AF_INET,SOCK_RAW,IPPROTO_ICMP)){PingSocket.DisplayError ("WSA_PING_ASYNC","CPingPlusDlg::InitSockets");return FALSE;}return TRUE;}3、获取winsocket设置信息BOOL CPingPlusDlg::FetchWinsockSettings(){SysTCPIP STcpIp;if (!STcpIp.WinsockVersion(&wsaData)){MessageBox ("No valid winsock.dll detected","CPingPlusDlg::OnInitDialog",MB_OK|MB_SYSTEMMODAL);return FALSE;}if (!STcpIp.GetLocalHostName (&m_LocalHost)){gethostname(CurrentHostName, MAXHOSTNAME);}else{memcpy (CurrentHostName, m_LocalHost, m_LocalHost.GetLength());CurrentHostName[m_LocalHost.GetLength()] = 0;}m_LocalHost = CurrentHostName;if (!STcpIp.GetDomainName(&LocalDomainName))LocalDomainName = "";m_LocalHost += "." + LocalDomainName;memcpy (CurrentHostName, m_LocalHost, m_LocalHost.GetLength());CurrentHostName[m_LocalHost.GetLength()] = 0;if (!STcpIp.GetNSName (&LocalNameServer))LocalNameServer = "";m_NameServer = "Name Server: " + LocalNameServer;SetDlgItemText (IDC_LocalHost, m_LocalHost);SetDlgItemText (IDC_NameServer, m_NameServer); LoadRegValues();SetDlgItemText (IDC_DEST, HostName);return TRUE;}4、发送ping信息void CPingPlusDlg::SendPing(void){PingSent = TRUE;PingSocket.icmpCurSeq++;PingSocket.icmpCurId = (USHORT)GetCurrentProcessId(); PingSocket.icmpHostAddress = HostIPAddress();if (PingSocket.icmpHostAddress == NULL)return;if (icmpTracing){icmpPingTTL++; }if (PingSocket.SetTTL (icmpPingTTL) == SOCKET_ERROR) { PingSocket.DisplayError ("setsocket(TTL)","CPingPlusDlg::SendPing");return; }Sleep (100);// 用蓝色箭头显示序列号及相应信息SetTraceSequence (PingSocket.icmpCurSeq,m_TraceList.GetItemCount(),Icon_BlueArrow);PingSocket.icmpSockAddr.sin_family = PF_INET;PingSocket.icmpSockAddr.sin_addr.s_addr = PingSocket.icmpHostAddress;PingSocket.icmpSockAddr.sin_port = 0;StartTimer();if (PingSocket.Ping (pIcmpBuffer, icmpDataLen) == SOCKET_ERROR)PingSocket.DisplayError("Ping", "CPingPlusDlg::SendPing");}5、设置超时时间int CIcmp::SetTTL(int TTL){int Result;Result = setsockopt (icmpSocket, IPPROTO_IP, IP_TTL, (LPSTR)&TTL, sizeof(int)); if (Result == SOCKET_ERROR){icmpSocketErrorMod = 1;icmpSocketError = WSAGetLastError(); }return Result;}6、Ping函数int CIcmp::Ping (LPSTR pIcmpBuffer, int DataLen){int Result;int IcmpBufferSize = DataLen + IcmpHeaderLength;pIcmpHeader = (LPIcmpHeader)pIcmpBuffer;memset (pIcmpBuffer, 'E', IcmpBufferSize);memset (pIcmpHeader, 0, IcmpHeaderLength);pIcmpHeader->IcmpType = ICMP_ECHO;pIcmpHeader->IcmpCode = 0;pIcmpHeader->IcmpChecksum = 0;pIcmpHeader->IcmpId = icmpCurId;pIcmpHeader->IcmpSeq = icmpCurSeq;pIcmpHeader->IcmpTimestamp = GetCurrentTime();pIcmpHeader->IcmpChecksum = IcmpChecksum ((USHORT FAR *)pIcmpBuffer,IcmpBufferSize); icmpPingSentAt = GetCurrentTime();Result = sendto (icmpSocket,pIcmpBuffer,IcmpBufferSize,0,(LPSOCKADDR)&icmpSockAddr,sizeof icmpSockAddr);if (Result == SOCKET_ERROR){ icmpSocketError = WSAGetLastError();icmpSocketErrorMod = 1;}return Result;}7、校验和函数unsigned short CIcmp::IcmpChecksum(unsigned short FAR *lpBuf, int Len) {register long ChkSum = 0L;while (Len > 1){ ChkSum += *(lpBuf++);Len -= sizeof (USHORT); }if (Len)ChkSum += *(UCHAR *)lpBuf;ChkSum = (ChkSum & 0xffff) + (ChkSum>>16);ChkSum += (ChkSum >> 16);#pragma warning(disable : 4244)return (~ChkSum);#pragma warning(default : 4244)}8、Receive函数int CIcmp::Receive(LPSTR pIcmpBuffer, int IcmpBufferSize) {LPSOCKADDR pRcvSockAddr = (LPSOCKADDR)&rcvSockAddr; int Result;int RcvIpHdrLen;icmpPingReceivedAt = GetTickCount();icmpCurId = 0;rcvSockAddr.sin_family = AF_INET;rcvSockAddr.sin_addr.s_addr = INADDR_ANY;rcvSockAddr.sin_port = 0;RcvIpHdrLen = sizeof rcvSockAddr;Result = recvfrom (icmpSocket,pIcmpBuffer,IcmpBufferSize,0,pRcvSockAddr,&RcvIpHdrLen);if (Result == SOCKET_ERROR){ icmpSocketError = WSAGetLastError();icmpSocketErrorMod = 1;DisplayError ("Receive","CIcmp::Receive");return Result;}icmpRcvLen = Result;pIpHeader = (LPIpHeader)pIcmpBuffer;RcvIpHdrLen = pIpHeader->HeaderLength * 4;if (Result < RcvIpHdrLen + ICMP_MIN){MessageBox(NULL,"Short message!","CIcmp::Receive",MB_OK|MB_SYSTEMMODAL);icmpSocketErrorMod = 2;return Result;}pIcmpHeader = (LPIcmpHeader)(pIcmpBuffer + RcvIpHdrLen);icmpCurId = pIcmpHeader->IcmpId;icmpRoundTripTime = icmpPingReceivedAt - pIcmpHeader->IcmpTimestamp;if (pIcmpHeader->IcmpType != ICMP_ECHOREPLY){return Result;}icmpCurSeq = pIcmpHeader->IcmpSeq;return Result;}五、运行结果用ping命令测试本地主机的ip地址六、心得体会通过本次课程设计,我感觉到自己在编程方面,能力还十分欠缺。