已阅读5页,还剩12页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
计算机网络课程设计报告题目: Ping程序的实现 姓 名: 学 号: 班 级: 指导老师: 湖南科技大学计算机科学与工程学院二零一四年 六月目录1、课程设计任务描述12、设计原理及相关知识12.1设计原理12.2相关知识23、需求分析23.1功能需求23.2性能需求33.3界面需求34系统设计及实现34.1系统设计34.2系统实现45、设计总结135.1 完成的工作及评价135.2 遇到的问题及解决过程135.3 心得体会及建议146、使用说明14参考文献141、课程设计任务描述 另写一个程序,取代windows下的Ping程序命令,可以Ping指定主机、一批主机,并显示输出结果。2、设计原理及相关知识2.1设计原理ping命令的工作原理1 是:向网络上的另一个主机系统发送ICMP报文,如果指定系统得到了报文,它将把报文一模一样地传回给发送者,通过返回的信息来判断网络的连接状况。要实现直接对IP和ICMP包进行操作,设计采用RAW模式的SOCKET编程,实现网络的连通性测试,探测主机到主机之间是否可以通信,如果不能ping到某台主机,表明不能和这台主机建立连接。Ping程序是面向向用户的应用程序,该程序使用ICMP的封装机制,通过IP协议来工作。2.2相关知识了解ping命令实现原理2 ,就要了解ping命令所使用到的TCP/IP协议。PING利用ICMP协议包来测试另一个主机是否可达。原理是用类型码为0的ICMP发送请求,收到请求主机则用类型码为8 的ICMP回应。Ping程序来计算时间间隔,并计算有多少个包被送达。用户就可以判断网络的大致情况。ICMP协议是IP层的 一个协议,但是由于差错报告在发送给报文源发方时可能也要经过若干子网,因此牵涉到路由选择等问题,所以ICMP报文需通过IP协议来发送。ICMP数据 报的数据发送前需要两级封装:首先添加ICMP报头形成ICMP报文,再添加IP报头形成IP数据报。TCP/IP应用于传输层之上,TCP/IP应用程序需要调用传输层的接口才能实现应用程序之间的通讯。应用层通过传输层进行数据通信时,TCP和UDP会遇到同时为多个应用程序进程提供并发服务的问题。多个TCP连接或多个应用程序进程可能需要通过同一个TCP协议端口传输数据。为了区别不同的应用程序进程和连接,许多计算机操作系统为应用程序与TCPIP协议交互提供了称为套接字(Socket)的接口。套接字3 接口是对网络中不同主机之间应用进程双向通信端点的抽象。提供了应用进程利用协议栈交换数据的机制。两个应用进程只要分别连接自己的套接字,就能方便通过计算机网络进行通信,不用去管网络的复杂结构,也不用管数据传送是复杂过程。3、需求分析3.1功能需求实现的 ping命令,能用于测试一个主机到另一个主机间的联通情况。程序能实现基本的ping操作,发送ICMP回显请求报文(可以更改发送的报文数目),接收显应答报文。显示发送数据包个数;接收数据包个数;丢失包个数,最大时间,最小时间以及平均时间。3.2性能需求能真实的的反映两台主机的联通情况3.3界面需求界面需要显示明确,当联通失败时能让人一眼就看出问题所在。4系统设计及实现4.1系统设计创建通信的套接字-将地址、端口信息与套接字绑定-构建IP包头与ICMP包头-发送构建的数据包-接收对方主机的回应-给出程序反馈信息系统执行的流程图如下图4.1所示:是开始输入ping的主机IP判断WSAStartup函数是否初始化成功创建套接字,设置套接字属性构建IP包头与ICMP包头循环发送4次数据包接收并解析数据包显示Ping的结果关闭清除结束否初始化协议图4.14.2系统实现(1)模块或函数功能描述void ping(int argc,char *argv):ping()函数是本程序的核心部分,它通过调用其他模块的函数来实现,其主要步骤包括初始化winsock,初始化协议,创建套接字,名字解析。int pack(int pack_no):构建数据报void send_packet(void):发送数据报void recv_packet(void):接收数据报 int unpack(unsigned char *buf,int len):剥去ICMP报头加显示unsigned short cal_checksum(unsigned short *buffer, int size); /求校验和函数void free():用于释放占用的资源,包括关闭套接字和释放winsock(2)关键的代码IP报头字段数据结构struct IPunsigned char ip_hl:4; /首部长度unsigned char ip_ver:4; /IP版本号unsigned char ip_tos; /服务类型unsigned short ip_len; /总长度unsigned short ip_id; /标识unsigned short ip_off; /标志位 unsigned char ip_ttl; /生存时间unsigned char ip_port; /协议类型(TCP、UDP等)unsigned short ip_checksum; /ip首部校验和 unsigned long ip_source; /源ip地址unsigned long ip_dest; /目的ip地址;ICMP报头字段数据结构struct ICMP unsigned char icmp_type; / 消息类型 unsigned char icmp_code; / 代码 unsigned short icmp_checksum; / 校验和 unsigned short icmp_id; / 用来惟一标识此请求的ID号,通常设置为进程ID unsigned short icmp_seq; / 序列号unsigned long icmp_data; / 时间戳;Ping函数void ping(int argc,char *argv)WSADATA wsadata;/WSADATA数据结构 struct hostent *host;struct protoent *protocol;char *par_host;par_host=argv1;pid=getpid(); /获取main的进程id,用于设置icmp的标志符 /使用Socket的程序在使用Socket之前必须调用WSAStartup函数完成对Winsock服务的初始化 /初始化winsock不成功if(WSAStartup(0x1010,&wsadata)!=0)printf(wsastartup errorn);exit(1);/初始化协议if( (protocol=getprotobyname(ICMP) )=NULL) printf(getprotobyname errorn); exit(1); /printf(所选协议的协议名:%snn,protocol-p_name);/printf(以主机字节顺序排列的协议号为:%dnn,protocol-p_proto); /套接字创建不成功 if(sockfd=socket(AF_INET,SOCK_RAW,protocol-p_proto)0)printf(socket errorn);exit(1); /设置套接字属性 if(setsockopt(sockfd,SOL_SOCKET,SO_RCVTIMEO,(char*)&timeout,sizeof(timeout)h_addr,host-h_length); /将获取到的IP值赋给目的地地址中的相应字段if(host=gethostbyaddr(host-h_addr,4,PF_INET)/ 将ip解析为主机名par_host=host-h_name;else/或者输出不明的主机if(dest_addr.sin_addr.s_addr=inet_addr(par_host)=INADDR_NONE)printf(Unknow host %sn,par_host);exit(1); printf(nPinging %s %s with %d bytes of data:nn,inet_ntoa(dest_addr.sin_addr),par_host,SEND_SIZE);发送数据报void send_packet() int packetsize; static int pack_no=0; packetsize=pack(pack_no+); /sendpacket为要发送的内容,由pack()函数设定,dest_addr是目的地址 if( sendto(sockfd,(char *)sendpacket,packetsize,0,(struct sockaddr *)&dest_addr,sizeof(dest_addr) )=0)success=unpack(recvpacket,n); else if (WSAGetLastError() = WSAETIMEDOUT) printf(Request timed out.n); return; while(!success); 构建数据报int pack(int pack_no ) int packsize; struct ICMP *icmp; packsize=8+SEND_SIZE; icmp=(struct ICMP*)sendpacket; /填充icmp数据内容 icmp-icmp_type=ICMP_ECHO; /填充类型 icmp-icmp_code=0; /填充代码 icmp-icmp_seq=pack_no; /填充序列号 icmp-icmp_id=pid; /填充ID icmp-icmp_data=GetTickCount(); icmp-icmp_checksum=0; icmp-icmp_checksum=cal_checksum( (unsigned short *)icmp,packsize); return packsize; 剥去ICMP报头加显示 int unpack(unsigned char *buf,int len) struct IP *ip; struct ICMP *icmp; double time; int iphdrlen; ip=(struct IP *)buf; iphdrlen=ip-ip_hl*4;/求ip报头长度,即ip报头的长度标志乘4 icmp=(struct ICMP *)(buf+iphdrlen); /越过ip报头,指向ICMP报头 /确保所接收的是我所发的的ICMP的回应 if( (icmp-icmp_type=ICMP_ECHOREPLY) & (icmp-icmp_id=pid) ) /读取icmp数据len=len-iphdrlen-8; time=GetTickCount()-icmp-icmp_data; if( timeip_ttl); timesreceived_no-1=time;/记录时间else printf(Request timed out.n); return 1; return 0; 求校验和函数unsigned short cal_checksum(unsigned short *buffer, int size)unsigned long cksum=0; /把ICMP报头二进制数据以2字节为单位累加起来 while(size1)cksum+=*buffer+;size-=2; /unsigned short长度为2,size最终为1或0(数据长度为奇数或偶数)if(size=1) /如果数据长度为奇数,将最后一个字节扩展到双字cksum+=*(unsigned char*)buffer; /对每个16bit进行二进制反码求和 即对双字高16位和低16位相加,取反后得到校验和 cksum = (cksum 16) + (cksum & 0xffff); cksum += (cksum 16); return (unsigned short)(cksum);释放占用的资源void free()/关闭套接字if(closesocket(sockfd)=SOCKET_ERROR) printf(closesocket failed with error%dn,WSAGetLastError();/释放winsockif(WSACleanup()=SOCKET_ERROR) printf(WSACleanup failed with error %dn,WSAGetLastError(); 主函数void main()int select;int i;char str15;int argc;char *argv2;printf(-n);printf( ping指定目的主机 请按 1 nn);printf( 更改向目的主机发送的报文数目 请按 2 nn);printf( 退出系统 3 nn);printf(-nn);printf(请选择:);scanf(%d,&select); while(select3) if(select=2)printf(n请输入指定向目的主机发送的报文数目(1000):);scanf(%d,&SEND_COUNT);printf(n请输入所要ping的主机ip地址:);scanf(%s,&str);/输入目的ipargc=2;argv0=-t;argv1=str; /存目的IP if(select=2)printf(n请输入指定向目的主机发送的报文数目(1000):);scanf(%d,&SEND_COUNT); ping(argc,argv);for(i=0;iSEND_COUNT;i+) /循环发送数据包 send_packet(); recv_packet(); Sleep(1000); /等待1s double maxt=0;double mint=times0;double sum=0;for(i=0;ireceived_no;i+)maxt=max(timesi,maxt);mint=min(timesi,mint);sum=sum+timesi;printf(nPing statistics for %s:n,inet_ntoa(dest_addr.sin_addr);printf( Packets: Send = %d, Received = %d, Lose = %d n,SEND_COUNT,received_no,SEND_COUNT-received_no,(SEND_COUNT-received_no)/SEND_COUNT*100); if(received_no=SEND_COUNT)printf(Approximate round trip times in milli-scends:n);printf( Minimum = %.0fms, Maximum = %.0fms, Average = %.0fmsnn,maxt,mint,sum/SEND_COUNT);received_no=0;free();printf(-n);printf( ping指定目的主机 请按 1 nn);printf( 更改向目的主机发送的报文数目 请按 2 nn);printf( 退出系统 3 nn);printf(-nn);printf(请选择:);scanf(%d,&select);(3)实现界面图4.25、设计总结5.1 完成的工作及评价通过这几天的学习及设计,本程序已经能够可以基本取代windows下的Ping程序命令,结果显示明确,达到了课程设计所要求的目标。 5.2 遇到的问题及解决过程(1)对Ping的工作原理不熟悉。刚开始时对Ping不太了解以至于不知道如何下手编程,通过网络和书本知道了什么是Ping,Ping的工作原理。(2)不懂套接字编程原理。在编程时会用到有很多以前没用到过的函数,特别时套接字相关的函数。每当遇到这些函数时,
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025福建漳州市福康医院招聘劳务派遣工作人员19人笔试考试参考试题及答案解析
- 2025福建某国企泉州分公司招聘1人考试笔试备考题库及答案解析
- 2025年下半年鹤壁职业技术学院招聘急需短缺人才2人考试笔试参考题库附答案解析
- 2025中国能建陕西院智能配网公司招聘笔试考试备考试题及答案解析
- 2025年潍坊市技师学院公开招聘高层次、高技能人才(10人)笔试考试备考题库及答案解析
- 2025江苏南京邮电大学招聘劳务派遣工作人员2人(第二批)考试笔试备考试题及答案解析
- 美甲师岗前评优竞赛考核试卷含答案
- 氯化苯装置操作工创新应用能力考核试卷含答案
- 2025豫章师范学院招聘司机2人考试笔试备考题库及答案解析
- 2025西藏昌都市人民医院招聘40人考试笔试模拟试题及答案解析
- 《TCQAE2024软件物料清单构成和要求》
- 幼儿园中班语言《七彩虾》课件
- 储气罐事故安全应急预案
- 磷化铝熏蒸作业安全培训课件
- 信创基础知识培训课件
- 《思想道德与法治》教案
- 闲置设备管理流程与规范手册
- 消防应急疏散培训
- 重庆A卷2022-2024年中考满分作文45篇
- 安全异常处置培训课件
- 九型人格心理测试题及释义108题
评论
0/150
提交评论