网络实验课程设计ping马聪敏Word格式.docx
《网络实验课程设计ping马聪敏Word格式.docx》由会员分享,可在线阅读,更多相关《网络实验课程设计ping马聪敏Word格式.docx(12页珍藏版)》请在冰豆网上搜索。
日期:
2013年6月4日
一、课程设计的目的与要求
1.1.目的:
1.1.1任务:
设计并实现一个Ping程序,以掌握UDP套接字的使用以及ICMP协议中ECHO报文的发送和接受方法。
1.1.2目的:
加深对课堂讲授知识的理解,熟练掌握基本的网络编程技术和方法,建立网络编程整体概念,使得学生初步具有研究、设计、编制和调试网络程序的能力。
1.1.3要求:
熟悉有关定义、概念和实现算法,设计出程序流程框图和数据结构,编写出完整的源程序,基本功能完善,方便易用,操作无误。
1.1.4学生要求人数:
1人。
1.2.要求:
用标准的UDP套接字和ECHO报文实现一个简单的基于UDP的Ping程序,要求:
1.2.1发送方发送ECHO报文,远程主机对发送方返回响应;
1.2.2发送方能够确定他和被探测机器之间的往返时延。
二、设计正文
2.1总体设计
2.1.1功能模块设计
本系统共有4个模块,分别是初始化模块、功能控制模块、数据控制模块、数据报解读模块和ping测试模块,如图2.1所示。
各模块功能描述如下。
图2.1.1系统模块图
(1)初始化模块。
改模块用于初始化各个全局变量,为全局变量赋初始值;
初始化,加载库。
(2)功能控制模块。
改模块是被其它模块调用,其功能包括获取参数、计算校验和填充数据报文、释放占用资源和显示用户帮助。
(3)数据报解读模块。
改模块用于解读接收到的报文和选项。
(4)测试模块。
改模块是本程序的核心模块,调用其他模块实现其功能,主要是实现的功能。
2.1.2系统流程图
系统执行的流程图2.1.2所示。
程序首先用AppWizard从VC++中生成一个基于对话框的工程MyPing,界面如下图:
将Ping服务封装成一个类CPing。
在Ping.h中,先定义ICMP报数据结构常量:
#defineIP_RECORD_ROUTE0x7
#defineDEF_PACKET_SIZE32
#defineMAX_PACKET1024
#defineMAX_IP_HDR_SIZE60
#defineICMP_ECHO8
#defineICMP_ECHOREPLY0
#defineICMP_MIN8
程序流程图2.1
typedefstruct_iphdr定义IP报文格式
typedefstruct_icmphdr定义ICMP报文格式
typedefstruct_ipoptionhdrIP头选项结构,当socket可选项设置成IPOPTIONS使用这个结构。
用classCPing解析。
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地址。
I_tye:
ICMP 报文类型。
I_code:
该类型中的代码号,一种ICMP报文的类型号和该类型中的代码号共同决定。
、
I_cksum:
I_seq:
序列号,序列号从0开始,每发送一次新的回显请求就加1.
Timestamp:
时间。
在CPing的构造函数代码中,发送ICMP数据报的函数Ping先创建一个Socket,Socket类型是SOCK_RAW,用的是ICMP协议,我把它设置成ICMP包头选项,最后解析数据包。
在这个函数中,CleanUp函数负责清除Socket,DecodeIPOptions函数解析IP头的参数,checksum函数负责对ICMP数据包校验,SET函数设置Ping参数。
2.1.3ping()函数流程图
ping()函数是本程序的核心部分它调用其他模块的函数来实现,其主要步骤包括创建接字,设置路由选项(如果需要的话)、设置接收和发送超时值、名字解析(如果需要的话)、分配内存、创建ICMP报文、发送ICMP请求报文、接收ICMP应答报文和解读ICMP报文。
其执行流程如图2.2所示。
图2.2
三、课程设计总结或结论
3.1实验结果
程序运行的主界面:
输入后显示的结果:
3.2总结
本次实现是大学以来做的最完整的一次实验,我觉得对书本上的知识要求的比较高,我回去又复习了计算机网络中ICMP和IP相关的部分,对于它们的报文格式和每个字段的含义在编程的时候有了更深刻的认识。
还有一点就是之前一直使用VC++中Application,这次对VC++系统的学习了下,学着用AppWizard编写有可视界面的程序,对于界面中每个button的监听还不是很懂,在同学的帮助下基本完成了,但是我的程序存在一个问题,就是无法PING主机地址,这个问题我会继续改好的。
总的来说,通过这个实验,我学会了系统的设计一个应用程序,并且调试得相对完整了。
四、参考文献
[1]曹衍龙,.《VC++网络编程精选》.清华大学出版社,第二版,2006年。
附录(设计流程图、程序、表格、数据等)
核心源程序:
Ping.h中主要函数:
classCPing
{
public:
voidSetConfigure(char*host,BOOLrecordrout=FALSE,intsize=DEF_PACKET_SIZE);
voidDecodeIPOptions(char*buf,intbytes);
voidCleanup();
voidPing(inttimeout=1000);
SOCKETm_hSocket;
IpOptionHeaderm_ipopt;
SOCKADDR_INm_addrDest;
SOCKADDR_INm_addrFrom;
char*icmp_data;
char*recvbuf;
USHORTseq_no;
char*lpdest;
intdatasize;
BOOLm_bRecordRout;
CMyPingDlg*m_dlg;
CPing(CMyPingDlg*dlg);
virtual~CPing();
private:
voidDecodeICMPHeader(char*buf,intbytes,SOCKADDR_IN*from);
USHORTchecksum(USHORT*buffer,intsize);
voidFillICMPData(char*icmp_data,intdatasize);
};
#endif
Ping.cpp中CPing的构造函数代码:
CPing:
:
CPing(CMyPingDlg*dlg)
m_dlg=dlg;
icmp_data=NULL;
seq_no=0;
recvbuf=NULL;
m_bRecordRout=FALSE;
lpdest=NULL;
datasize=DEF_PACKET_SIZE;
WSADATAwsaData;
if(WSAStartup(MAKEWORD(2,2),&
wsaData)!
=0)
{
AfxMessageBox("
Sorry,youcannotloadsocketdll!
"
);
return;
}
m_hSocket=INVALID_SOCKET;
}
~CPing()
if(lpdest)
delete[]lpdest;
Cleanup()清除Socket
voidCPing:
Cleanup()
if(m_hSocket!
=INVALID_SOCKET)
closesocket(m_hSocket);
HeapFree(GetProcessHeap(),0,recvbuf);
HeapFree(GetProcessHeap(),0,icmp_data);
//WSACleanup();
return;
解析IP数据包:
DecodeIPOptions(char*buf,intbytes)
IpOptionHeader*ipopt=NULL;
IN_ADDRinaddr;
inti;
HOSTENT*host=NULL;
ipopt=(IpOptionHeader*)(buf+20);
m_dlg->
m_result+="
Ping结果:
\r\n"
;
SetDlgItemText(IDC_EDIT2,m_dlg->
m_result);
for(i=0;
i<
(ipopt->
ptr/4)-1;
i++)
inaddr.S_un.S_addr=ipopt->
addr[i];
if(i!
{
//m_dlg->
"
m_dlg->
}
host=gethostbyaddr((char*)&
inaddr.S_un.S_addr,
sizeof(inaddr.S_un.S_addr),AF_INET);
CStringtemp;
if(host)
temp.Format("
(%-15s)%s\r\n"
inet_ntoa(inaddr),host->
h_name);
m_result+=temp;
else
(%-15s)\r\n"
inet_ntoa(inaddr));
return;
Ping按钮的消息响应:
voidCMyPingDlg:
OnPing()
//TODO:
Addyourcontrolnotificationhandlercodehere
CButton*checkbox=(CButton*)GetDlgItem(IDC_CHECK_ROUTE);
intstate=checkbox->
GetCheck();
charhost[100];
GetDlgItemText(IDC_HOST,host,100);
m_pinger.SetConfigure(host,state);
m_pinger.Ping();
m_result+="
ping完成!
\r\n--------------------\r\n"
SetDlgItemText(IDC_EDIT2,m_result);
m_pinger.Cleanup();