Tracert-程序設計報告_第1頁
Tracert-程序設計報告_第2頁
Tracert-程序設計報告_第3頁
Tracert-程序設計報告_第4頁
Tracert-程序設計報告_第5頁
已閱讀5頁,還剩6頁未讀 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

設計報告課程計算機網絡設計名稱Tracert程序專業(yè)班級計科112同組人學號姓名實驗日期指導教師成績年月日一、設計目的和要求1、實驗目的1.熟悉原始套接字編程。

2.了解網絡的結構。

3.了解網絡傳輸?shù)讓訁f(xié)議。

4.熟悉掌握

ICMP協(xié)議的工作原理和路由跟蹤原理。

5.掌握vc6.0下程序調試、運行的基本方法。

6.通過實驗熟悉協(xié)議的應用。2、實驗要求1、通過實驗,可以使程序記錄并顯示了數(shù)據(jù)報從源端機器傳送到目標機器的過程中所經過的路由器的IP地址,并且記錄了數(shù)據(jù)報到達每個路由器所需要的時間。認真觀察到達每個路由器的時間有什么區(qū)別,從而熟練掌握tracert的工作原理和ICMP報文協(xié)議。

2、當我們不能通過網絡訪問目的設備時,網絡管理員就需要判斷是哪里出了問題。問題不僅僅會出現(xiàn)在最終目的設備,也可能出現(xiàn)在轉發(fā)數(shù)據(jù)包的中間路由器。二、設計說明(包括設計分析,系統(tǒng)運行環(huán)境,設計中的重點和難點,輸入和輸出輸出條件等)路由是把信息從源穿過網絡傳遞到目的地的行為,在傳輸過程中,遇到一系列的中間節(jié)點。這些中間節(jié)點構成了路由跟蹤的依據(jù)。路由跟蹤是在路由的基礎上提出的問題,是利用路由跟蹤實用程序于確定IP數(shù)據(jù)報訪問目標所采取的路徑。當我們不能通過網絡訪問目的設備時,網絡運行者就需要判斷是哪里出了問題。問題不僅僅會出現(xiàn)在最終目的設備,也可能出現(xiàn)在轉發(fā)數(shù)據(jù)包的中間路由器。解決方法是了解了IP數(shù)據(jù)報訪問目標所采取的路徑,將發(fā)現(xiàn)網絡布網簡單拓撲,確定路由斷點即可解決網絡故障。操作系統(tǒng)中的tracert或traceroute路由跟蹤程序,通過它可以查看到達目標地址所經過的路徑。它的作用與ping有類似之處使用ping可以檢查是否連接,如果不通,一般不好準確判斷哪一個節(jié)點出錯,而使用tracert則可以準確判斷出錯的部分。系統(tǒng)實現(xiàn)路由的跟蹤,每經過一個路由,要求得到經過該路由節(jié)點的地址,也就是說輸入目標信息,可以得到本地主機到目標經過的所有中間節(jié)點。這些中間節(jié)點用IP地址標識。并要求對跟蹤跳數(shù),每一跳等待時間可控。為了讓系統(tǒng)更加完善,首先要測試目標的連通性,系統(tǒng)中也要實現(xiàn)目標探測功能,即Ping功能。當數(shù)據(jù)報從你的計算機經過多個網關傳送到目的地時,Tracert命令可以用來跟蹤數(shù)據(jù)報使用的路由(路徑)。該實用程序跟蹤的路徑是源計算機到目的地的一條路徑,不能保證或認為數(shù)據(jù)報總遵循這個路徑。Tracert是一個運行得比較慢的命令(如果你指定的目標地址比較遠),每個路由器你大約需要給它15秒鐘。

Tracert使用時只需要在tracert后面跟一個IP地址或URL,Tracert會進行相應的域名轉換,Tracert一般用來檢測故障的位置,你可以用tracertIP在哪個環(huán)節(jié)上出了問題,雖然還是沒有確定是什么問題,但它已經告訴了我們問題所在的地方。

三、系統(tǒng)詳細設計(包括程序流程、主要函數(shù)等)開始開始使用UDP協(xié)議創(chuàng)建原始UDP包使用UDP協(xié)議創(chuàng)建原始UDP包目的主機回應答或達到最大跳站目的主機回應答或達到最大跳站 YTTL++(初始值為1)NTTL++(初始值為1)填充UDP數(shù)據(jù)包并發(fā)送填充UDP數(shù)據(jù)包并發(fā)送有數(shù)據(jù)報到達? N有數(shù)據(jù)報到達?有預期數(shù)據(jù)報? Y有預期數(shù)據(jù)報? NY解析數(shù)據(jù)報并顯示輸出超時,顯示超時信息解析數(shù)據(jù)報并顯示輸出超時,顯示超時信息釋放各種資源顯示結果信息釋放各種資源顯示結果信息結束結束四、程序源代碼及注釋#include<iostream.h>#include<iomanip.h>#include<winsock2.h>#include<ws2tcpip.h>#include"itracert.h"http:////////////////////////////////////////////////////////intmain(intargc,char*argv[]){ //檢查命令行參數(shù) if(argc!=2) { cerr<<"\nUsage:itracertip_or_hostname\n"; return-1; } //初始化winsock2環(huán)境 WSADATAwsa; if(WSAStartup(MAKEWORD(2,2),&wsa)!=0) { cerr<<"\nFailedtoinitializetheWinSock2DLL\n" <<"errorcode:"<<WSAGetLastError()<<endl; return-1; } //將命令行參數(shù)轉換為IP地址 u_longulDestIP=inet_addr(argv[1]); if(ulDestIP==INADDR_NONE) { //轉換不成功時按域名解析 hostent*pHostent=gethostbyname(argv[1]); if(pHostent) { ulDestIP=(*(in_addr*)pHostent->h_addr).s_addr; //輸出屏幕信息 cout<<"\nTracingrouteto"<<argv[1] <<"["<<inet_ntoa(*(in_addr*)(&ulDestIP))<<"]" <<"withamaximumof"<<DEF_MAX_HOP<<"hops.\n"<<endl; } else//解析主機名失敗 { cerr<<"\nCouldnotresolvethehostname"<<argv[1]<<'\n' <<"errorcode:"<<WSAGetLastError()<<endl; WSACleanup(); return-1; } } else { //輸出屏幕信息 cout<<"\nTracingrouteto"<<argv[1] <<"withamaximumof"<<DEF_MAX_HOP<<"hops.\n"<<endl; } //填充目的Socket地址 sockaddr_indestSockAddr; ZeroMemory(&destSockAddr,sizeof(sockaddr_in)); destSockAddr.sin_family=AF_INET; destSockAddr.sin_addr.s_addr=ulDestIP; //使用ICMP協(xié)議創(chuàng)建RawSocket SOCKETsockRaw=WSASocket(AF_INET,SOCK_RAW,IPPROTO_ICMP,NULL,0,WSA_FLAG_OVERLAPPED); if(sockRaw==INVALID_SOCKET) { cerr<<"\nFailedtocreatearawsocket\n" <<"errorcode:"<<WSAGetLastError()<<endl; WSACleanup(); return-1; } //設置端口屬性 intiTimeout=DEF_ICMP_TIMEOUT; if(setsockopt(sockRaw,SOL_SOCKET,SO_RCVTIMEO,(char*)&iTimeout,sizeof(iTimeout))==SOCKET_ERROR) { cerr<<"\nFailedtosetrecvtimeout\n" <<"errorcode:"<<WSAGetLastError()<<endl; closesocket(sockRaw); WSACleanup(); return-1; } if(setsockopt(sockRaw,SOL_SOCKET,SO_SNDTIMEO,(char*)&iTimeout,sizeof(iTimeout))==SOCKET_ERROR) { cerr<<"\nFailedtosetsendtimeout\n" <<"errorcode:"<<WSAGetLastError()<<endl; closesocket(sockRaw); WSACleanup(); return-1; } //創(chuàng)建ICMP包發(fā)送緩沖區(qū)和接收緩沖區(qū) charIcmpSendBuf[sizeof(ICMP_HEADER)+DEF_ICMP_DATA_SIZE]; memset(IcmpSendBuf,0,sizeof(IcmpSendBuf)); charIcmpRecvBuf[MAX_ICMP_PACKET_SIZE]; memset(IcmpRecvBuf,0,sizeof(IcmpRecvBuf)); //填充待發(fā)送的ICMP包 ICMP_HEADER*pIcmpHeader=(ICMP_HEADER*)IcmpSendBuf; pIcmpHeader->type=ICMP_ECHO_REQUEST; pIcmpHeader->code=0; pIcmpHeader->id=(USHORT)GetCurrentProcessId(); memset(IcmpSendBuf+sizeof(ICMP_HEADER),'E',DEF_ICMP_DATA_SIZE); //開始探測路由 DECODE_RESULTstDecodeResult; BOOLbReachDestHost=FALSE; USHORTusSeqNo=0; intiTTL=1; intiMaxHop=DEF_MAX_HOP; while(!bReachDestHost&&iMaxHop--) { //設置IP數(shù)據(jù)報頭的ttl字段 setsockopt(sockRaw,IPPROTO_IP,IP_TTL,(char*)&iTTL,sizeof(iTTL)); //輸出當前跳站數(shù)作為路由信息序號 cout<<setw(3)<<iTTL<<flush; //填充ICMP數(shù)據(jù)報剩余字段 ((ICMP_HEADER*)IcmpSendBuf)->cksum=0; ((ICMP_HEADER*)IcmpSendBuf)->seq=htons(usSeqNo++); ((ICMP_HEADER*)IcmpSendBuf)->cksum=GenerateChecksum((USHORT*)IcmpSendBuf,sizeof(ICMP_HEADER)+DEF_ICMP_DATA_SIZE); //記錄序列號和當前時間 stDecodeResult.usSeqNo=((ICMP_HEADER*)IcmpSendBuf)->seq; stDecodeResult.dwRoundTripTime=GetTickCount(); //發(fā)送ICMP的EchoRequest數(shù)據(jù)報 if(sendto(sockRaw,IcmpSendBuf,sizeof(IcmpSendBuf),0, (sockaddr*)&destSockAddr,sizeof(destSockAddr))==SOCKET_ERROR) { //如果目的主機不可達則直接退出 if(WSAGetLastError()==WSAEHOSTUNREACH) cout<<'\t'<<"Destinationhostunreachable.\n" <<"\nTracecomplete.\n"<<endl; closesocket(sockRaw); WSACleanup(); return0; } //接收ICMP的EchoReply數(shù)據(jù)報 //因為收到的可能并非程序所期待的數(shù)據(jù)報,所以需要循環(huán)接收直到收到所要數(shù)據(jù)或超時 sockaddr_infrom; intiFromLen=sizeof(from); intiReadDataLen; while(1) { //等待數(shù)據(jù)到達 iReadDataLen=recvfrom(sockRaw,IcmpRecvBuf,MAX_ICMP_PACKET_SIZE, 0,(sockaddr*)&from,&iFromLen); if(iReadDataLen!=SOCKET_ERROR)//有數(shù)據(jù)包到達 { //解碼得到的數(shù)據(jù)包,如果解碼正確則跳出接收循環(huán)發(fā)送下一個EchoRequest包 if(DecodeIcmpResponse(IcmpRecvBuf,iReadDataLen,stDecodeResult)) { if(stDecodeResult.dwIPaddr.s_addr==destSockAddr.sin_addr.s_addr) bReachDestHost=TRUE; cout<<'\t'<<inet_ntoa(stDecodeResult.dwIPaddr)<<endl; break; } } elseif(WSAGetLastError()==WSAETIMEDOUT)//接收超時,打印星號 { cout<<setw(9)<<'*'<<'\t'<<"Requesttimedout."<<endl; break; } else { cerr<<"\nFailedtocallrecvfrom\n" <<"errorcode:"<<WSAGetLastError()<<endl; closesocket(sockRaw); WSACleanup(); return-1; } } //TTL值加1 iTTL++; } //輸出屏幕信息 cout<<"\nTracecomplete.\n"<<endl; closesocket(sockRaw); WSACleanup(); return0;}//產生網際校驗和USHORTGenerateChecksum(USHORT*pBuf,intiSize){ unsignedlongcksum=0; while(iSize>1) { cksum+=*pBuf++; iSize-=sizeof(USHORT); } if(iSize) cksum+=*(UCHAR*)pBuf; cksum=(cksum>>16)+(cksum&0xffff); cksum+=(cksum>>16); return(USHORT)(~cksum);}//解碼得到的數(shù)據(jù)報BOOLDecodeIcmpResponse(char*pBuf,intiPacketSize,DECODE_RESULT&stDecodeResult){ //檢查數(shù)據(jù)報大小的合法性 IP_HEADER*pIpHdr=(IP_HEADER*)pBuf; intiIpHdrLen=pIpHdr->hdr_len*4; if(iPacketSize<(int)(iIpHdrLen+sizeof(ICMP_HEADER))) returnFALSE; //按照ICMP包類型檢查id字段和序列號以確定是否是程序應接收的Icmp包 ICMP_HEADER*pIcmpHdr=(ICMP_HEADER*)(pBuf+iIpHdrLen); USHORTusID,usSquNo; if(pIcmpHdr->type==ICMP_ECHO_REPLY) { usID=pIcmpHdr->id; usSquNo=pIcmpHdr->seq; } elseif(pIcmpHdr->type==ICMP_TIMEOUT) { char*pInnerIpHdr=pBuf+iIpHdrLen+sizeof(ICMP_HEADER); //載荷中的IP頭 intiInnerIPHdrLen=((IP_HEADER*)pInnerIpHdr)->hdr_len*4;//載荷中的IP頭長 ICMP_HEADER*pInnerIcmpHdr=(ICMP_HEADER*)(pInnerIpHdr+iInnerIPHdrLen);//載荷中的ICMP頭 usID=pInnerIcmpHdr->id; usSquNo=pInnerIcmpHdr->seq; } else returnFALSE; if(usID!=(USHORT)GetCurrentProcessId()||usSquNo!=stDecodeResult.usSeqNo) returnFALSE; //處理正確收到的ICMP數(shù)據(jù)報 if(pIcmpHdr->type==ICMP_ECHO_REPLY|| pIcmpHdr->type==ICMP_TIMEOUT) { //返回解碼結果 stDecodeResult.dwIPaddr.s_addr=pIpHdr->sourceIP; stDecodeResult.dwRoundTripTime=GetTickCount()-

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論