版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1、<p><b> 目 錄</b></p><p><b> 1 設計目的1</b></p><p><b> 2 設計內容2</b></p><p><b> 3 程序流程2</b></p><p><b> 4 設計步
2、驟3</b></p><p><b> 5 設計總結10</b></p><p><b> 1 設計目的</b></p><p> 網絡通信課程設計是網絡工程專業(yè)的大型作業(yè)課。是培養(yǎng)計算機領域從事網絡技術及應用工作的高級工程技術人才的必修課程。</p><p> 本課的主要任
3、務是使學生隊所學的《計算機網絡》知識從實踐上有一個較清晰的了解。對當前計算機網絡的主要種類和常用的網絡協議有更進一步的深入認識。學會計算機網絡設計和日常管理及維護的最基本方法。</p><p> 網絡編程簡單的理解就兩臺計算機相互通訊數據,通過使用套接字來達到進程通信目的編程就是網絡編程。網絡編程最主要工作就是在發(fā)送端把信息通過規(guī)定好的協議進行組包,在接收端按照規(guī)定好的協議把包進行解析,從而提取出相應的信息,達
4、到通信的目的。中間最主要的就是數據包的組裝,數據包的過濾,數據包的捕獲,數據包的分析,當然最后再做一些處理。</p><p> 本次實驗運用C++的網絡編程相關知識,通過學習了解了TCP和UDP協議的基本知識和SOCKET編程的基本概念,完成tracert程序,實現ping功能和路由追蹤功能。</p><p><b> 2 設計內容</b></p>
5、<p><b> 一、學習實踐要求</b></p><p> 1.對計算機網絡的物理構成有清晰的了解;</p><p> 2.理解計算機網絡體系結構的內涵;</p><p> 3.熟悉計算機網絡的分類及常用的網絡協議;</p><p> 4.基于掌握計算機網絡軟件的開發(fā)方法;</p>&
6、lt;p> 5.具備管理計算機網絡的基本知識及技能。</p><p><b> 二、模塊功能</b></p><p> (1)pin功能:發(fā)送ICMP數據包到計算機,如有返回,顯示相應時間等。</p><p> ?。?)路由探測功能:依次ping途經的路由器或網關設備,依次顯示途經路由器的響應時間。</p><p
7、><b> 3 程序流程</b></p><p><b> 圖1 流程圖</b></p><p><b> 4 設計步驟</b></p><p> 一、程序運行結果相關截圖</p><p><b> 圖2 運行結果</b></p&
8、gt;<p><b> 圖3 運行結果</b></p><p><b> 圖4 運行結果</b></p><p><b> 圖5 運行結果</b></p><p><b> 二、程序源代碼</b></p><p> #incl
9、ude <iostream></p><p> #include <winsock2.h></p><p> #include <ws2tcpip.h></p><p> using namespace std;</p><p> #pragma comment(lib, "Ws2_32.
10、lib")</p><p><b> //IP報頭</b></p><p> typedef struct</p><p><b> {</b></p><p> unsigned char hdr_len:4; //4位頭部長度</p><p&g
11、t; unsigned char version:4; //4位版本號</p><p> unsigned char tos; //8位服務類型</p><p> unsigned short total_len; //16位總長度</p><p> unsigned short identifier
12、; //16位標識符</p><p> unsigned short frag_and_flags; //3位標志加13位片偏移</p><p> unsigned char ttl; //8位生存時間</p><p> unsigned char protocol; //8位上層協議號&
13、lt;/p><p> unsigned short checksum; //16位校驗和</p><p> unsigned long sourceIP; //32位源IP地址</p><p> unsigned long destIP; //32位目的IP地址</p><p>
14、} IP_HEADER;</p><p><b> //ICMP報頭</b></p><p> typedef struct</p><p><b> {</b></p><p> BYTE type; //8位類型字段</p><p> BYTE c
15、ode; //8位代碼字段</p><p> USHORT cksum; //16位校驗和</p><p> USHORT id; //16位標識符</p><p> USHORT seq; //16位序列號</p><p> } ICMP_HEADER;</p><
16、p><b> //報文解碼結構</b></p><p> typedef struct</p><p><b> {</b></p><p> USHORT usSeqNo; //序列號</p><p> DWORD dwRoundTripTime; //
17、往返時間</p><p> in_addr dwIPaddr; //返回報文的IP地址</p><p> }DECODE_RESULT;</p><p> //計算網際校驗和函數</p><p> USHORT checksum(USHORT *pBuf,int iSize)</p><p>&l
18、t;b> {</b></p><p> unsigned long cksum=0;</p><p> while(iSize>1)</p><p><b> {</b></p><p> cksum+=*pBuf++;</p><p> iSize-=size
19、of(USHORT);</p><p><b> }</b></p><p><b> if(iSize)</b></p><p><b> {</b></p><p> cksum+=*(UCHAR *)pBuf;</p><p><b&
20、gt; }</b></p><p> cksum=(cksum>>16)+(cksum&0xffff);</p><p> cksum+=(cksum>>16);</p><p> return (USHORT)(~cksum);</p><p><b> }</b>
21、</p><p> //對數據包進行解碼</p><p> BOOL DecodeIcmpResponse(char * pBuf,int iPacketSize,DECODE_RESULT &DecodeResult,BYTE ICMP_ECHO_REPLY,BYTE ICMP_TIMEOUT)</p><p><b> {</b&
22、gt;</p><p> //檢查數據報大小的合法性</p><p> IP_HEADER* pIpHdr = (IP_HEADER*)pBuf;</p><p> int iIpHdrLen = pIpHdr->hdr_len * 4;</p><p> if (iPacketSize < (int)(iIpHdrLen
23、+sizeof(ICMP_HEADER)))</p><p> return FALSE;</p><p> //根據ICMP報文類型提取ID字段和序列號字段</p><p> ICMP_HEADER *pIcmpHdr=(ICMP_HEADER *)(pBuf+iIpHdrLen);</p><p> USHORT usID,usS
24、quNo;</p><p> if(pIcmpHdr->type==ICMP_ECHO_REPLY) //ICMP回顯應答報文</p><p><b> {</b></p><p> usID=pIcmpHdr->id; //報文ID</p><p> usSquNo=pI
25、cmpHdr->seq; //報文序列號</p><p><b> }</b></p><p> else if(pIcmpHdr->type==ICMP_TIMEOUT) //ICMP超時差錯報文</p><p><b> {</b></p><p> char *
26、 pInnerIpHdr=pBuf+iIpHdrLen+sizeof(ICMP_HEADER); //載荷中的IP頭</p><p> int iInnerIPHdrLen=((IP_HEADER *)pInnerIpHdr)->hdr_len*4; //載荷中的IP頭長</p><p> ICMP_HEADER
27、 * pInnerIcmpHdr=(ICMP_HEADER *)(pInnerIpHdr+iInnerIPHdrLen);//載荷中的ICMP頭</p><p> usID=pInnerIcmpHdr->id; //報文ID</p><p> usSquNo=pInnerIcmpHdr->seq; //序列號</p><p>&l
28、t;b> }</b></p><p><b> else</b></p><p><b> {</b></p><p> return false;</p><p><b> }</b></p><p> //檢查ID和序列
29、號以確定收到期待數據報</p><p> if(usID!=(USHORT)GetCurrentProcessId()||usSquNo!=DecodeResult.usSeqNo)</p><p><b> {</b></p><p> return false;</p><p><b> }<
30、/b></p><p> //記錄IP地址并計算往返時間</p><p> DecodeResult.dwIPaddr.s_addr=pIpHdr->sourceIP;</p><p> DecodeResult.dwRoundTripTime=GetTickCount()-DecodeResult.dwRoundTripTime;</p&g
31、t;<p> //處理正確收到的ICMP數據報</p><p> if (pIcmpHdr->type == ICMP_ECHO_REPLY ||pIcmpHdr->type == ICMP_TIMEOUT)</p><p><b> {</b></p><p> //輸出往返時間信息</p>&
32、lt;p> if(DecodeResult.dwRoundTripTime)</p><p> cout<<" "<<DecodeResult.dwRoundTripTime<<"ms"<<flush;</p><p><b> else</b></p&
33、gt;<p> cout<<" "<<"<1ms"<<flush;</p><p><b> }</b></p><p> return true;</p><p><b> }</b></p>
34、<p> void main()</p><p><b> {</b></p><p> //初始化Windows sockets網絡環(huán)境</p><p> WSADATA wsa;</p><p> WSAStartup(MAKEWORD(2,2),&wsa);</p><
35、;p> char IpAddress[255];</p><p> cout<<"請輸入一個IP地址或域名:";</p><p> cin>>IpAddress;</p><p><b> //得到IP地址</b></p><p> u_long ulDestI
36、P=inet_addr(IpAddress);</p><p> //轉換不成功時按域名解析</p><p> if(ulDestIP==INADDR_NONE)</p><p><b> {</b></p><p> hostent * pHostent=gethostbyname(IpAddress);<
37、;/p><p> if(pHostent)</p><p><b> {</b></p><p> ulDestIP=(*(in_addr*)pHostent->h_addr).s_addr;</p><p><b> }</b></p><p><b>
38、 else</b></p><p><b> {</b></p><p> cout<<"輸入的IP地址或域名無效!"<<endl;</p><p> WSACleanup();</p><p><b> return;</b><
39、;/p><p><b> }</b></p><p><b> }</b></p><p> cout<<"Tracing roote to "<<IpAddress<<" with a maximum of 30 hops.\n"<<
40、;endl;</p><p> //填充目地端socket地址</p><p> sockaddr_in destSockAddr;</p><p> ZeroMemory(&destSockAddr,sizeof(sockaddr_in));</p><p> destSockAddr.sin_family=AF_INET;
41、</p><p> destSockAddr.sin_addr.s_addr=ulDestIP;</p><p><b> //創(chuàng)建原始套接字</b></p><p> SOCKET sockRaw=WSASocket(AF_INET,SOCK_RAW,IPPROTO_ICMP,NULL,0,WSA_FLAG_OVERLAPPED);&l
42、t;/p><p><b> //超時時間</b></p><p> int iTimeout=3000;</p><p><b> //接收超時</b></p><p> setsockopt(sockRaw,SOL_SOCKET,SO_RCVTIMEO,(char *)&iTimeou
43、t,sizeof(iTimeout));</p><p><b> //發(fā)送超時</b></p><p> setsockopt(sockRaw,SOL_SOCKET,SO_SNDTIMEO,(char *)&iTimeout,sizeof(iTimeout));</p><p> //構造ICMP回顯請求消息,并以TTL遞增的順
44、序發(fā)送報文</p><p> //ICMP類型字段</p><p> const BYTE ICMP_ECHO_REQUEST=8; //請求回顯</p><p> const BYTE ICMP_ECHO_REPLY=0; //回顯應答</p><p> const BYTE ICMP_TIMEOUT=11;
45、 //傳輸超時</p><p><b> //其他常量定義</b></p><p> const int DEF_ICMP_DATA_SIZE=32; //ICMP報文默認數據字段長度</p><p> const int MAX_ICMP_PACKET_SIZE=1024;//ICMP報文最大長度(包括報頭)</p>
46、<p> const DWORD DEF_ICMP_TIMEOUT=3000; //回顯應答超時時間</p><p> const int DEF_MAX_HOP=30; //最大跳站數</p><p> //填充ICMP報文中每次發(fā)送時不變的字段</p><p> char IcmpSendBuf[sizeof(I
47、CMP_HEADER)+DEF_ICMP_DATA_SIZE]; //發(fā)送緩沖區(qū)</p><p> memset(IcmpSendBuf, 0, sizeof(IcmpSendBuf)); //初始化發(fā)送緩沖區(qū)</p><p> char IcmpRecvBuf[MAX_ICMP_PACKET_SIZE];
48、 //接收緩沖區(qū)</p><p> memset(IcmpRecvBuf, 0, sizeof(IcmpRecvBuf)); //初始化接收緩沖區(qū)</p><p> ICMP_HEADER * pIcmpHeader=(ICMP_HEADER*)IcmpSendBuf;</p><p> pIcmpHeader->type
49、=ICMP_ECHO_REQUEST; //類型為請求回顯</p><p> pIcmpHeader->code=0; //代碼字段為0</p><p> pIcmpHeader->id=(USHORT)GetCurrentProcessId(); //ID字段為當前進程號</p>
50、<p> memset(IcmpSendBuf+sizeof(ICMP_HEADER),'E',DEF_ICMP_DATA_SIZE);//數據字段</p><p> USHORT usSeqNo=0; //ICMP報文序列號</p><p> int iTTL=1; //TTL初始值為1<
51、;/p><p> BOOL bReachDestHost=FALSE; //循環(huán)退出標志</p><p> int iMaxHot=DEF_MAX_HOP; //循環(huán)的最大次數</p><p> DECODE_RESULT DecodeResult; //傳遞給報文解碼函數的結構化參數</p><p> while(!b
52、ReachDestHost&&iMaxHot--)</p><p><b> {</b></p><p> //設置IP報頭的TTL字段</p><p> setsockopt(sockRaw,IPPROTO_IP,IP_TTL,(char *)&iTTL,sizeof(iTTL));</p><
53、;p> cout<<iTTL<<flush; //輸出當前序號</p><p> //填充ICMP報文中每次發(fā)送變化的字段</p><p> ((ICMP_HEADER *)IcmpSendBuf)->cksum=0; //校驗和先置為0</p><p> ((ICMP_HEADER *)IcmpSendBuf
54、)->seq=htons(usSeqNo++); //填充序列號</p><p> ((ICMP_HEADER *)IcmpSendBuf)->cksum=checksum((USHORT *)IcmpSendBuf,sizeof(ICMP_HEADER)+DEF_ICMP_DATA_SIZE); //計算校驗和</p><p> //記錄序列號和當前時間<
55、;/p><p> DecodeResult.usSeqNo=((ICMP_HEADER*)IcmpSendBuf)->seq; //當前序號</p><p> DecodeResult.dwRoundTripTime=GetTickCount(); //當前時間</p><p> //發(fā)送TCP回顯請求信息</p>
56、<p> sendto(sockRaw,IcmpSendBuf,sizeof(IcmpSendBuf),0,(sockaddr*)&destSockAddr,sizeof(destSockAddr));</p><p> //接收ICMP差錯報文并進行解析處理</p><p> sockaddr_in from; //對端socket地址<
57、;/p><p> int iFromLen=sizeof(from); //地址結構大小</p><p> int iReadDataLen; //接收數據長度</p><p><b> while(1)</b></p><p><b> {</b></p>
58、;<p><b> //接收數據</b></p><p> iReadDataLen=recvfrom(sockRaw,IcmpRecvBuf,MAX_ICMP_PACKET_SIZE,0,(sockaddr*)&from,&iFromLen);</p><p> if(iReadDataLen!=SOCKET_ERROR)
59、//有數據到達</p><p><b> {</b></p><p> //對數據包進行解碼</p><p> if(DecodeIcmpResponse(IcmpRecvBuf,iReadDataLen,DecodeResult,ICMP_ECHO_REPLY,ICMP_TIMEOUT))</p><p><
60、;b> {</b></p><p> //到達目的地,退出循環(huán)</p><p> if(DecodeResult.dwIPaddr.s_addr==destSockAddr.sin_addr.s_addr)</p><p> bReachDestHost=true;</p><p><b> //輸出IP
61、地址</b></p><p> cout<<'\t'<<inet_ntoa(DecodeResult.dwIPaddr)<<endl;</p><p><b> break;</b></p><p><b> }</b></p><p
62、><b> }</b></p><p> else if(WSAGetLastError()==WSAETIMEDOUT) //接收超時,輸出*號</p><p><b> {</b></p><p> cout<<" *"<<'\t&
63、#39;<<"Request timed out."<<endl;</p><p><b> break;</b></p><p><b> }</b></p><p><b> else</b></p><p><b&g
64、t; {</b></p><p><b> break;</b></p><p><b> }</b></p><p><b> }</b></p><p> iTTL++; //遞增TTL值</p><p><b>
65、; }</b></p><p><b> }</b></p><p><b> 5 設計總結</b></p><p> 通過這次課程設計,讓我受益匪淺,使我掌握了網絡通信編程的基本思想。實習的時候遇到很多不會的東西,通過問老師同學,上網自己搜索得到答案,解決問題。畫流程圖,剛開始怎么都不會,畫好后每次改
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 眾賞文庫僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 網絡課程設計---使用vc++編程實現網絡嗅探器
- 網絡嗅探器的設計與實現課程設計
- 課程設計:網絡嗅探器設計 sniffer vc++平臺
- 信息安全課程設計---網絡嗅探器的設計與實現
- 課程設計--基于c#的網絡嗅探器的設計和實現
- ip網絡數據嗅探器設計
- 網絡嗅探器-計算機網絡課程設計說明書
- 網絡嗅探器畢業(yè)論文
- 網絡編程課程設計報告--圖片瀏覽器
- 嗅探器和網絡監(jiān)聽器外文翻譯
- 網絡信息安全概況課程基于c#的網絡嗅探器的和實現
- 網絡協議編程應用課程設計
- 基于LINUX的網絡嗅探器的設計與實現.pdf
- 上機1:基于winpcap的網絡嗅探器設計與實現
- 網絡編程課程設計---網絡聊天室
- 基于c#的網絡嗅探器設計與實現【開題報告】
- atm網絡編程cs課程設計--模擬atm機網絡編程
- web課程設計 《web網絡編程技術》課程設計報告
- 基于c#的網絡嗅探器設計與實現【畢業(yè)設計】
- 基于c#的網絡嗅探器設計與實現【文獻綜述】
評論
0/150
提交評論