网络通信程序设计实验二路由跟踪.docx
- 文档编号:4007139
- 上传时间:2022-11-27
- 格式:DOCX
- 页数:12
- 大小:74.48KB
网络通信程序设计实验二路由跟踪.docx
《网络通信程序设计实验二路由跟踪.docx》由会员分享,可在线阅读,更多相关《网络通信程序设计实验二路由跟踪.docx(12页珍藏版)》请在冰豆网上搜索。
网络通信程序设计实验二路由跟踪
实验报告
课程名称网络通信程序设计
实验仪器计算机
实验名称路由跟踪
系别__计算机学院_
专业___
班级/学号__
学生
实验日期2021年4月6日
成绩___________________
指导教师焦健
实验二路由跟踪实验
一、实验目的
学习分析程序功能构造。
熟悉ICMP协议的工作原理和路由跟踪的原理。
掌握VC6.0下程序调试、运行的根本方法。
二、实验原理
路由跟踪的实现就是巧妙地利用了ICMP报文的TTL超时报文。
其实现过程如下:
源主机先向目的主机发送一个回应请求报文〔类型8〕,TTL值设为1,第一个路由器收到后将TTL减1,这样TTL变为0,分组被废除。
同时路由器向源主机发送一个TTL超时报文〔类型为11〕,报文的IP中的源IP地址就是第一个路由器的地址,源主机就可以通过对该报文进展分析,得到第一个路由器的地址。
接着发送TTL等于2的报文得到第二个路由器地址,再发TTL等于3的报文。
如此下去直到收到目的主机的回应应答报文〔类型为0〕或目的不可达报文〔类型为3〕,或者到了最大跳数(要检测路由器个数的最大值)。
可以看到,对TTL的设置是实现跟踪的关键,使用函数setsockopt(m_Sock,IPPROTO_IP,IP_TTL,(LPSTR)&TTL,sizeof(int))可以对其进展设置,m_Sock是所创立的套接字,IP_TTL说明是进展TTL设置,TTL即是要设置的TTL值,为一个整形数值。
其实现流程如图1所示:
图1路由跟踪流程图
三、实验容
1、按照附录容给RouteTrace程序添加代码,增加注释,调试程序通过。
源代码:
RouteTrace.cpp
//RouteTrace.cpp:
Definestheclassbehaviorsfortheapplication.
#include"stdafx.h"
#include"RouteTrace.h"
#include"RouteTraceDlg.h"
#ifdef_DEBUG
#definenewDEBUG_NEW
#undefTHIS_FILE
staticcharTHIS_FILE[]=__FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
//CRouteTraceApp
BEGIN_MESSAGE_MAP(CRouteTraceApp,CWinApp)
//{{AFX_MSG_MAP(CRouteTraceApp)
//NOTE-theClassWizardwilladdandremovemappingmacroshere.
//DONOTEDITwhatyouseeintheseblocksofgeneratedcode!
//}}AFX_MSG
ON_MAND(ID_HELP,CWinApp:
:
OnHelp)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
//CRouteTraceAppconstruction
CRouteTraceApp:
:
CRouteTraceApp()
{
//TODO:
addconstructioncodehere,
//PlaceallsignificantinitializationinInitInstance
}
/////////////////////////////////////////////////////////////////////////////
//TheoneandonlyCRouteTraceAppobject
CRouteTraceApptheApp;
/////////////////////////////////////////////////////////////////////////////
//CRouteTraceAppinitialization
BOOLCRouteTraceApp:
:
InitInstance()
{
AfxEnableControlContainer();
//Standardinitialization
//Ifyouarenotusingthesefeaturesandwishtoreducethesize
//ofyourfinalexecutable,youshouldremovefromthefollowing
//thespecificinitializationroutinesyoudonotneed.
#ifdef_AFXDLL
Enable3dControls();//CallthiswhenusingMFCinasharedDLL
#else
Enable3dControlsStatic();//CallthiswhenlinkingtoMFCstatically
#endif
CRouteTraceDlgdlg;
m_pMainWnd=&dlg;
intnResponse=dlg.DoModal();
if(nResponse==IDOK)
{//TODO:
Placecodeheretohandlewhenthedialogis
//dismissedwithOK
}
elseif(nResponse==IDCANCEL)
{
//TODO:
Placecodeheretohandlewhenthedialogis
//dismissedwithCancel
}
//Sincethedialoghasbeenclosed,returnFALSEsothatweexitthe
//application,ratherthanstarttheapplication'smessagepump.
returnFALSE;
}
源代码:
ICMP.cpp
//ICMP.cpp:
implementationoftheCICMPclass.
#include"stdafx.h"
#include"RouteTrace.h"
#include"ICMP.h"
#include"ws2tcpip.h"
#ifdef_DEBUG
#undefTHIS_FILE
staticcharTHIS_FILE[]=__FILE__;
#definenewDEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
//Construction/Destruction
//////////////////////////////////////////////////////////////////////
CICMP:
:
CICMP()
{winsock=0;
m_pIp=NULL;
m_pIcmp=NULL;
m_pIp=(IP_HEAD*)newBYTE[MAX_PACKET];
m_pIcmp=(ICMP_HEAD*)newBYTE[MAX_PACKET];
}
CICMP:
:
~CICMP()
{delete[]m_pIp;
delete[]m_pIcmp;
}
BOOLCICMP:
:
Initialize()
{WSADATAwsadata;
if(WSAStartup(MAKEWORD(2,1),&wsadata))
{AfxMessageBox("WSAStartup初始化失败!
");
returnFALSE;
}
winsock=WSASocket(AF_INET,//建立socket
SOCK_RAW,
IPPROTO_ICMP,
NULL,0,0);
if(!
winsock){
AfxMessageBox("Socket创立失败!
");
returnFALSE;}
inttimeout=5000;
setsockopt(winsock,SOL_SOCKET,SO_RCVTIMEO,(char*)&timeout,// 设置接收超时
sizeof(timeout));
timeout=5000;
setsockopt(winsock,SOL_SOCKET,SO_SNDTIMEO,(char*)&timeout,//设置发送超时
sizeof(timeout));
returnTRUE;
}
voidCICMP:
:
Uninitialize()//释放Socket
{
if(winsock)
closesocket(winsock);
WSACleanup();
}
USHORTCICMP:
:
CheckSum(USHORT*buffer,intsize)//计算校验和
{
unsignedlongcksum=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);
}
BOOLCICMP:
:
SendICMPPack(char*pAddr)
{sockaddr_insockAddr;
memset((void*)&sockAddr,0,sizeof(sockAddr));
sockAddr.sin_family=AF_INET;
sockAddr.sin_port=0;
sockAddr.sin_addr.S_un.S_addr=inet_addr(pAddr);
returnSendICMPPack(&sockAddr);
}
//----------------设置TTL--------------------
intCICMP:
:
SetTTL(intTTL)
{intnRet=setsockopt(winsock,IPPROTO_IP,IP_TTL,(LPSTR)&TTL,sizeof(int));
if(nRet==SOCKET_ERROR)
{CStringttlerr;
ttlerr.Format("设置TTL错误!
");
AfxMessageBox(ttlerr);
return0;
}
return1;
}
//--------------------发送---------------------------
BOOLCICMP:
:
SendICMPPack(sockaddr_in*pAddr)
{//填充ICMP数据各项
intstate;
char*p_data;
m_pIcmp->type=ICMP_ECHO;
m_pIcmp->code=0;
m_pIcmp->ID=(USHORT)GetCurrentProcessId();
m_pIcmp->number=0;
m_pIcmp->time=GetTickCount();
m_pIcmp->cksum=0;
//填充数据
p_data=((char*)m_pIcmp+sizeof(ICMP_HEAD));
memset((char*)p_data,'0',DEF_PACKET);
//检查和
m_pIcmp->cksum=CheckSum((USHORT*)m_pIcmp,
DEF_PACKET+sizeof(ICMP_HEAD));
//发送数据
state=sendto(winsock,(char*)m_pIcmp,
DEF_PACKET+sizeof(ICMP_HEAD),
NULL,(structsockaddr*)pAddr,sizeof(sockaddr));
if(state==SOCKET_ERROR){
if(GetLastError()==WSAETIMEDOUT)
m_strInfo="连接超时!
(发送)";
else
m_strInfo="出现未知发送错误!
";
returnFALSE;
}
if(state m_strInfo="发送数据错误! "; returnFALSE; } memcpy((void*)&m_sockAddr,(void*)pAddr, sizeof(sockaddr_in)); returnTRUE; } //----------------------接收数据---------------------------- BOOLCICMP: : RecvICMPPack() { intstate; intlen=sizeof(sockaddr_in); char*addr; structhostent*lpHostent=NULL; intMaxfd=1;//监视的最大的文件描述符值+1 fd_setreadFdSet;//设置文件描述符 structtimevalTimeout; addr=inet_ntoa(m_sockAddr.sin_addr); FD_ZERO(&readFdSet); FD_SET(winsock,&readFdSet); Maxfd=max(Maxfd,winsock)+1; Timeout.tv_sec=10;//设置响应时间限制 Timeout.tv_usec=0; inte=: : select(Maxfd,&readFdSet,NULL,NULL,&Timeout);//获取多路复用套接字的响应结果 if(e<=0){ routeaddr="****"; routestate=1; RouteState="超时未知"; returnFALSE; } if(! FD_ISSET(winsock,&readFdSet)) returnFALSE; state=recvfrom(winsock,(char*)m_pIp,MAX_PACKET,0,(structsockaddr*)&m_sockAddr,&len); if(state==SOCKET_ERROR){ if(WSAGetLastError()==WSAETIMEDOUT) { m_strInfo.Format("接收超时,路由跟踪失败! "); routestate=0; RouteState="路由跟踪失败! "; } else m_strInfo="未知接收错误! "; returnFALSE; } //分析数据 intipheadlen; ipheadlen=m_pIp->HeadLen*4; if(state<(ipheadlen+MIN_PACKET)){ m_strInfo="目的地址的响应数据不正确"; returnFALSE; } ICMP_HEAD*p_icmprev; p_icmprev=(ICMP_HEAD*)((char*)m_pIp+ipheadlen); switch(p_icmprev->type) { caseICMP_ECHOREPLY: //收到正常回显 { m_strInfo.Format("接收到%s%d字节响应数据,响应时间: %dms.", inet_ntoa(m_sockAddr.sin_addr),len,GetTickCount()-p_icmprev->time); routeaddr=addr; routestate=0; RouteState="到达目的主机! "; returnTRUE; break; } caseICMP_TTLOUT: //TTL超时 { routeaddr=inet_ntoa(m_sockAddr.sin_addr); routestate=1; RouteState="测试到路由器! "; returnTRUE; break; } caseICMP_DESUNREACH: //目的不可达 {m_strInfo="目的不可达! "; routestate=0; RouteState="目的不可达"; returnTRUE; break; } default: {routestate=0; routeaddr="***"; m_strInfo="未知错误! "; RouteState="不明状态! "; } } returnTRUE; } 2、命令行窗口下运行: tracertc: \iknow\docshare\data\cur_work\.sohu.163.命令,记录运行结果和IP地址。 3、用RouteTrace程序执行到2中IP的路由跟踪,记录结果。 4、由于该程序在编制过程中没有考虑路由器不返回应答报文这一情况,因此程序在未收到报文的情况下执行处理流程存在显示错误,请找出问题所在的代码将其更正,正确显示为如下的结果: 四、实验要求及考前须知 代码主要容已经添加了注释,重点理解ICMP.cpp中接收数据局部的代码。 充分利用网络搜索,查找相关资料。 五、实验总结 此次实验主要是学习分析程序功能构造,在VisualC++6.0中调试通过,从而熟悉ICMP协议的工作原理和路由跟踪的原理。 同时还可以根据实际需要修改程序中的参数,通过这次学习对路由跟踪有了更深刻的认识。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 网络 通信 程序设计 实验 路由 跟踪