网络通信程序设计实验二路由跟踪.docx

上传人:b****3 文档编号:4007139 上传时间:2022-11-27 格式:DOCX 页数:12 大小:74.48KB
下载 相关 举报
网络通信程序设计实验二路由跟踪.docx_第1页
第1页 / 共12页
网络通信程序设计实验二路由跟踪.docx_第2页
第2页 / 共12页
网络通信程序设计实验二路由跟踪.docx_第3页
第3页 / 共12页
网络通信程序设计实验二路由跟踪.docx_第4页
第4页 / 共12页
网络通信程序设计实验二路由跟踪.docx_第5页
第5页 / 共12页
点击查看更多>>
下载资源
资源描述

网络通信程序设计实验二路由跟踪.docx

《网络通信程序设计实验二路由跟踪.docx》由会员分享,可在线阅读,更多相关《网络通信程序设计实验二路由跟踪.docx(12页珍藏版)》请在冰豆网上搜索。

网络通信程序设计实验二路由跟踪.docx

网络通信程序设计实验二路由跟踪

实验报告

课程名称网络通信程序设计

实验仪器计算机

实验名称路由跟踪

 

系别__计算机学院_

专业___

班级/学号__

学生

实验日期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协议的工作原理和路由跟踪的原理。

同时还可以根据实际需要修改程序中的参数,通过这次学习对路由跟踪有了更深刻的认识。

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > IT计算机 > 计算机硬件及网络

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1