2023年全國碩士研究生考試考研英語一試題真題(含答案詳解+作文范文)_第1頁
已閱讀1頁,還剩21頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

1、<p><b>  計算機(jī)網(wǎng)絡(luò)課程設(shè)計</b></p><p>  一、設(shè)計內(nèi)容及設(shè)計要求</p><p>  1.1課程設(shè)計內(nèi)容:</p><p>  利用ICMP數(shù)據(jù)包,通過使用ICMP的回送和回送響應(yīng)消息來確定當(dāng)前網(wǎng)絡(luò)中處于活動狀態(tài)的主機(jī),即ping消息的請求和應(yīng)答,將發(fā)送的ICMP的數(shù)據(jù)包類型設(shè)置為回送請求(類型號為8),并顯

2、示在標(biāo)準(zhǔn)輸出上。用命令行形式運(yùn)行:scanhost Start_IP End_IP,其中scanhost為程序名;Start_IP為被搜索網(wǎng)段的開始IP;End_IP為被搜索網(wǎng)段的結(jié)束IP地址。</p><p>  1.2課程設(shè)計目的:</p><p>  IP協(xié)議的優(yōu)點(diǎn)是簡單,但缺少差錯控制和查詢機(jī)制,而網(wǎng)際控制報文協(xié)議(ICMP具有補(bǔ)充IP功能的作用。在網(wǎng)絡(luò)管理中,常常要確定當(dāng)前網(wǎng)絡(luò)在

3、紅處于活動狀態(tài)的主機(jī),這時可以通過ICMP的回送和回送響應(yīng)消息來完成這項(xiàng)工作。這課程設(shè)計的目的就是編制程序,利用ICMP數(shù)據(jù)包,發(fā)現(xiàn)網(wǎng)絡(luò)中的活動主機(jī),即ping消息的請求和應(yīng)答。通過課程設(shè)計,熟悉ICMP報文的結(jié)構(gòu),對ICMP協(xié)議有更好的理解和認(rèn)識,培養(yǎng)綜合運(yùn)用網(wǎng)絡(luò)知識解決實(shí)際問題能力。</p><p>  1.3課程設(shè)計要求:</p><p>  設(shè)計程序,其功能是發(fā)送ICMP數(shù)據(jù)包,以

4、獲取指定望段中的活動主機(jī),并將結(jié)果顯示在標(biāo)準(zhǔn)輸出設(shè)備上程序的具體要求如下:</p><p><b>  1.用命令形式運(yùn)行</b></p><p>  scanhost為程序名;start_ip為被搜索網(wǎng)段;end_ip為被搜索網(wǎng)段的結(jié)束IP地址。如在命令行輸入 scanhost 192.168.0.1 192.168.0.100</p><p

5、><b>  2.輸出格式</b></p><p>  活動主機(jī)1的IP地址</p><p>  活動主機(jī)2的IP地址</p><p>  活動主機(jī) n的IP地址</p><p><b>  二、總體設(shè)計</b></p><p><b>  2.1設(shè)計原理&l

6、t;/b></p><p>  首先對ICMP報文的格式有一定的了解,ICMP報文是在IP數(shù)據(jù)報內(nèi)部傳輸?shù)?,其結(jié)構(gòu)如圖所示:</p><p><b>  IP數(shù)據(jù)報</b></p><p>  IP首部 ICMP報文</p><p>  ICMP報文的格式如圖所示:</p><p>

7、;  0 7 8 15 16 31(位)</p><p>  所有報文的前4個字節(jié)都是一樣的,但是其它字節(jié)則互不相同。其中類型字段可以有15個不同的值,以描述特定類型的ICMP報文,某些ICMP報文還使用代碼字段的值來進(jìn)一步描述不用的條件。按驗(yàn)和字段為2字節(jié),校驗(yàn)的范圍是整個ICMP報文。檢驗(yàn)和是必須的,其計算方法與I

8、P協(xié)議頭部校驗(yàn)和的計算方法一樣。</p><p>  各種類型的ICMP報文如圖所示(ICMP報文類型),不同類型由報文中的類型字段和代碼字段來共同決定。</p><p>  課程設(shè)計的目的是發(fā)現(xiàn)網(wǎng)絡(luò)中的活動主機(jī),就是使用ICMP的回送和回送響應(yīng)消息發(fā)現(xiàn)網(wǎng)絡(luò)中的活動主機(jī),即Ping消息的請求和應(yīng)答。那幺,發(fā)送的ICMP的數(shù)據(jù)包類型設(shè)置為回送請求(類型號為8)。</p><

9、;p>  本程序使用的原始套接字生成ICMP請求/應(yīng)答報文來進(jìn)行活動主機(jī)的探查。這個程序使用的是回送請求和應(yīng)答消息。程序的大致思想是把ICMP的數(shù)據(jù)報類型設(shè)置為回送請求,將它發(fā)送給網(wǎng)絡(luò)上的一個IP地址,如果這個IP地址已經(jīng)被占用的話,那么使用位于這個IP地址的主機(jī)上的TCP/IP軟件就能接受到這個ICMP回送請求,從而返回一個ICMP回送請求(類型號為0)信息。信息封裝在一個IP包中,我們需要解析該IP包,從中找到ICMP數(shù)據(jù)信息

10、,相反,如果這個IP地址沒有人使用,那么發(fā)送的ICMP回送請求在設(shè)定的延時內(nèi)就不可能得到響應(yīng)。</p><p><b>  2.2概要設(shè)計</b></p><p><b>  主程序流程圖</b></p><p><b>  子線程流程圖</b></p><p><b&g

11、t;  三、詳細(xì)設(shè)計及代碼</b></p><p>  3.1 ICMP報文分析</p><p>  ICMP是一種差錯和控制報文協(xié)議,用于傳輸錯誤報告和控制信息。</p><p>  ICMP報文分為頭部和數(shù)據(jù)部分。ICMP報文封裝在IP數(shù)據(jù)報中傳輸。IP報頭中的類型為1時,表示報文的數(shù)據(jù)部分為ICMP報文。雖然ICMP報文由IP報文傳輸,但是并不能認(rèn)

12、為ICMP是IP的上層協(xié)議,而是IP協(xié)議的有機(jī)補(bǔ)充。把ICMP報文放在IP包中,是要利用IP的轉(zhuǎn)發(fā)功能。</p><p>  類型(TYPE)是一個字節(jié),表示ICMP消息的類型。代碼(CODE)也是一個字節(jié),表示報文類型的下一步信息。校驗(yàn)和共有兩個字節(jié),提供對整個ICMP報文的校驗(yàn)和(和IP報文類型的進(jìn)一步信息)。校驗(yàn)和共兩個字節(jié),提供對整個ICMP報文的校驗(yàn)和。按照協(xié)議的功能來分,ICMP報文可以分為</

13、p><p>  [1]. ICMP差錯報文 </p><p>  包括目的不可達(dá)報告,超時報告,參數(shù)出錯報告。</p><p>  [2] .ICMP控制報文</p><p>  包括擁塞控制和源抑制報文,路游控制和重定向報文</p><p>  [3] .ICMP測試報文</p><p>  包括

14、請求應(yīng)答報文,時戳請求應(yīng)答報文。</p><p>  本課程設(shè)計就是使用ICMP請求/應(yīng)答報文來測試目的主機(jī)是否存在,請求者想某特定的主機(jī)發(fā)送請求,其中包含任選的數(shù)據(jù)。目的主機(jī)收到請求后,發(fā)送應(yīng)答報文。在同一時刻,一臺機(jī)器可以同時向多臺主機(jī)發(fā)送請求報文。ICMP報文格式如圖所示:</p><p>  ICMP回送報文格式如下圖所示:</p><p><b>

15、;  3.2程序功能分析</b></p><p>  本程序使用原始套接字生成ICMP報文來進(jìn)行活動主機(jī)的探查。這個程序使用的是回送請求與應(yīng)答信息。程序的大致思想是把ICMP的數(shù)據(jù)包類型設(shè)置為回送請求,將它發(fā)送給網(wǎng)絡(luò)上的一個IP地址,如果這個IP地址已經(jīng)被占用的話,那么使用位于這個IP地址的主機(jī)上的TCP/IP軟件就能夠接受到這個ICMP回送請求,從而返回一個ICMP回送響應(yīng)(類型號為0)信息。信息封

16、裝在一個IP包中,需要解析該IP包,從中找到ICMP數(shù)據(jù)信息。相反,如果這個IP地址沒有人使用,那么發(fā)送的ICMP回送請求在設(shè)定的延時內(nèi)就不可能得到響應(yīng)。</p><p>  在初始化原始套接字之后,本程序就要開始在一個IP網(wǎng)段內(nèi)尋找活動主機(jī)。因?yàn)橐獙ふ一顒拥闹鳈C(jī)可能很多,為節(jié)省時間可以采用多線程編程。結(jié)合核心代碼對程序的具體進(jìn)行分析。</p><p>  3.2.1使用原始套接字<

17、/p><p>  為了實(shí)現(xiàn)發(fā)送/監(jiān)聽ICMP抱文,必須使用原始套接字,創(chuàng)建原始套接字的代碼如下:SOCKET sockraw;</p><p>  sockraw=WSASocket(AF_INET,SOCK_RAW,IPPROTO_ICMP,NULL,0,wsa_flag_overlapped);</p><p>  在WSASocket函數(shù)中,我們使用IPPROTO

18、_ICMP表示接受ICMP數(shù)據(jù)包,為了使用發(fā)送接受超時設(shè)置(設(shè)置SO_RCVTIMEO或SO_SNDTIMEO),必須將標(biāo)志位置為WSA_FLAG_OVERLAPPED。然后調(diào)用setsockopt函數(shù)設(shè)置讀取遲延。在setsockopt函數(shù)中,sockraw是之前創(chuàng)建的原始套接字,設(shè)置SOL_SOCKET表明使用基本套接字處理ICMP抱文。設(shè)置SO_RCVTIMEO表示使用接受超時設(shè)置,SOSNDTIMEO表示使用發(fā)送超時設(shè)置,在這里

19、,超時時間均設(shè)置為1000ms。</p><p>  3.2.2定義IP頭部的數(shù)據(jù)結(jié)構(gòu)</p><p>  typedef struct iphdr{</p><p>  unsigned int headlen:4; //ip頭長度</p><p>  unsigned int wersion:4; //ip版本號</p&

20、gt;<p>  unsigned char tos; //服務(wù)類型</p><p>  unsigned short totallen; //ip包總長度</p><p>  unsigned short id; //ip號</p><p>  unsigned short flag; //標(biāo)記<

21、/p><p>  unsigned char ttl; //生存時間</p><p>  unsigned char prot; //協(xié)議(UDP TCP)</p><p>  unsigned short checksum; //校驗(yàn)和</p><p>  unsigned int sourceip;

22、//源ip</p><p>  unsigned int destip; //目的ip</p><p>  }IpHeader;</p><p>  3.2.3定義ICMP頭部數(shù)據(jù)結(jié)構(gòu)</p><p>  typedef struct icmphdr{</p><p>  BYTE type; //i

23、cmp類型碼,回送請求的類型碼為8</p><p>  BYTE code; //子類型碼,保存與特定ICMP報文類型相關(guān)的細(xì)節(jié)信息</p><p>  USHORT checksum; //校驗(yàn)和</p><p>  USHORT id; //ICMP報文id號</p><p>  USHORT se

24、q; //ICMP數(shù)據(jù)報的序列號</p><p>  }Icmpheader;</p><p>  3.2.4填充并發(fā)送請求類型的ICMP報文</p><p>  #define ICMP_ECHO 8 //請求回送</p><p>  #define DEF_PACKET_SIZE 32 //缺省數(shù)據(jù)

25、報長度</p><p>  #define MAX_PACKET 1024 //最大數(shù)據(jù)報長度</p><p>  #char icmp_data[MAX_PACKET]; //ICMP數(shù)據(jù)報最大可能長度</p><p>  Memset(icmp_data,0, MAX_PACKET) //將數(shù)據(jù)報清空初始化</p><p>  

26、Int datasize=DEF_PACKET_SIZE; //ICMP數(shù)據(jù)報報文體的額缺省長度</p><p>  Datasize+=sizeof(icmpHeader); //加上ICMP數(shù)據(jù)頭部</p><p>  icmp_header *icmp_hdr;</p><p>  char *datapart;</p><p>

27、  icmp_hdr=(icmpheader*)icmp_data;</p><p>  icmp_hdr->type=icmp_echo; //設(shè)置類型</p><p>  icmp_hdr->id=(ushort)getcurrentthreadid(); //設(shè)置其ID號為當(dāng)前線程號</p><p>  datapart=icmp_

28、data+sizeof(icmpheader); //計算出ICMP數(shù)據(jù)報的數(shù)據(jù)部分</p><p>  memset(datapart,'A',datasize-sizeof(icmphearder)); //填入數(shù)據(jù)</p><p>  ((IcmpHeader*)icmp_data)->seq=0; //序列號</p>&l

29、t;p>  ((IcmpHeader*)icmp_data)->check_sum=0; //先將檢驗(yàn)和置0</p><p>  ((IcmpHeader*)icmp_data)->checksum=checksum(USHORT*) icmp_data,data_size);</p><p>  Checksum 為計算校驗(yàn)和的函數(shù),設(shè)校驗(yàn)和初值為0,然后對數(shù)據(jù)每1

30、6位求異或,結(jié)果取反,便得校驗(yàn)和。其代碼如下:</p><p>  USHORT checksum(USHORT * buffer, int size) //計算校驗(yàn)和</p><p><b>  {</b></p><p>  unsinged long cksum=0;</p><p>  while (si

31、ze>1)</p><p><b>  {</b></p><p>  cksum+=*buffer++;</p><p>  size-=sizeof(ushort);</p><p><b>  }</b></p><p><b>  if(size)&l

32、t;/b></p><p><b>  {</b></p><p>  cksum+=*(uchar)buffer;</p><p><b>  }</b></p><p>  cksum=(cksum>>16)+(cksum&0xffff);</p><

33、;p>  cksum+=(cksum>>16);</p><p>  return (ushort)(-cksum);</p><p><b>  }</b></p><p>  填充ICMP報文之后,應(yīng)在ICMP報文之前加上IP報頭并發(fā)送出去??烧{(diào)用下面的代碼發(fā)送數(shù)據(jù)包。注意,這里的dest是填入目的主機(jī)的IP地址的一個so

34、ckaddr_in數(shù)據(jù)結(jié)構(gòu),IP_STRING是目的的主機(jī)的IP地址字符串。</p><p>  Struct sockaddr_in_dest;</p><p>  Dest.sin_family=AF_INET;</p><p>  Dest.sin_addr.s_addr=inet_addr(IP_STRING);</p><p>  

35、Sendto(sockraw,icmp_data,datasize,0,(sockaddr*)&dest,size of(dest));</p><p>  3.2.5解析數(shù)據(jù)包</p><p>  如果所ping的目的主機(jī)存在,那么它會發(fā)出一個回送應(yīng)答包。這是一個IP包,受到后解析此數(shù)據(jù)包并獲得其中的ICMP信息。根據(jù)IP報頭信息中的IP報頭長度字段,就可以得到ICMP報文的真實(shí)

36、地址。ICMP數(shù)據(jù)包中的IP地址就是活動主機(jī)的IP。代碼分析如下:</p><p>  #define ICMP_MIN 8</p><p>  #define MAX_PING_PACKET_SIZE(MAX_PACKET+sizeof(IpHeader))</p><p>  char *recvbuf=new[MAX_PING_PACKET_SIZE];<

37、;/p><p>  struct sockaddr_in dest,from,end;</p><p>  int formlen=sizeof(from);</p><p>  int bytes=recvfrom(sockraw,recvbuf,MAX_PACKET,0,(Struct sockaddr*)&from,&fromlen)</p&

38、gt;<p>  ipheader *iphdr;</p><p>  icmpheader *icmphdr;</p><p>  unsigned short iphdrlen;</p><p>  iphdr=(ipheader*)buf;</p><p>  iphdrlen=iphdr->headlen*4;

39、 //IP報頭的長度</p><p>  icmphdr=(icmpheader *)(buf+iphdrlen); //跳過IP頭</p><p>  //數(shù)據(jù)包太短 丟棄</p><p>  if(bytes<iphdrlen+icmp_min) return; //不是回送請求(ping應(yīng)答),丟棄<

40、/p><p>  if(icmphdr->type!=icmp_echo_reply) return; //ID不相符,丟棄</p><p>  if(icmphdr->id!=(USHORT)getcurrentthreadid()) return;</p><p>  //輸出正在使用的IP地址</p><p>  cout&l

41、t;<"活動主機(jī)"<<inet_ntoa(from->sin_addr)<<endl;</p><p><b>  3.2.6源代碼:</b></p><p>  //scanhost.h</p><p>  #pragma pack(4)</p><p>  #p

42、ragma comment(lib,"Ws2_32.lib")</p><p>  #define win32_LEAN_AND_MEAN</p><p>  #include <winsock2.h></p><p>  #include <stdio.h></p><p>  #include

43、<iostream.h></p><p>  #include <stdlib.h></p><p>  #include <sys/timeb.h></p><p>  #include <time.h></p><p>  //THE IP HEADER</p><p&g

44、t;  typedef struct iphdr{</p><p>  unsigned int headlen:4; //ip頭長度</p><p>  unsigned int wersion:4; //ip版本號</p><p>  unsigned char tos; //服務(wù)類型</p>

45、<p>  unsigned short totallen; //ip包總長度</p><p>  unsigned short id; //ip號</p><p>  unsigned short flag; //標(biāo)記</p><p>  unsigned char ttl; //生存時間</p&

46、gt;<p>  unsigned char prot; //協(xié)議(UDP TCP)</p><p>  unsigned short checksum; //校驗(yàn)和</p><p>  unsigned int sourceip; //源ip</p><p>  unsigned int destip; //目的

47、ip</p><p>  }IpHeader;</p><p>  //ICMP HEADER</p><p>  typedef struct icmphdr{</p><p>  BYTE type; //icmp類型碼,回送請求的類型碼為8</p><p>  BYTE code;

48、 //子類型碼,保存與特定ICMP報文類型相關(guān)的</p><p><b>  //節(jié)信息</b></p><p>  USHORT checksum; //校驗(yàn)和</p><p>  USHORT id; //ICMP報文id號</p><p>  USHORT seq

49、; //ICMP數(shù)據(jù)報的序列號</p><p>  }Icmpheader;</p><p>  #define ICMP_ECHO 8 //請求回送</p><p>  #define ICMP_ECHO_REPLY 0 //請求回應(yīng)</p><p>  #define ICMP_MIN 8

50、 //ICMP包頭長度(最小ICMP包長度)</p><p>  #define STATUS_FAILED 0xFFFF //錯誤碼</p><p>  #define DEF_PACKET_SIZE 32 //缺省數(shù)據(jù)報長度</p><p>  #define MAX_PACKET 1024 //最大數(shù)據(jù)報長度</p><

51、p>  #define MAX_PING_PACKET_SIZE (MAX_PACKET + sizeof(IpHeader)) //最大接受數(shù)據(jù)報長度</p><p>  void fill_icmp_date(char * ,int); //填充ICMP包</p><p>  USHORT checksum(USHORT *,int); //校驗(yàn)和函數(shù)</p>

52、;<p>  void decode_resp(char*,int,struct sockaddr_in *); //找到此數(shù)據(jù)報IP地址</p><p>  DWORD WINAPI FindIp(LPVOID pipaddrtemp); //線程調(diào)用子函數(shù)</p><p>  //scanhost.cpp</p><p>  #includ

53、e "scanhost.h"</p><p>  WSADATA wsadata;</p><p>  SOCKET sockraw;</p><p>  struct sockaddr_in dest, from,end;</p><p>  int fromlen = sizeof(from);</p>

54、<p>  char * recvbuf = new char[MAX_PING_PACKET_SIZE];</p><p>  unsigned int addr = 0;</p><p>  long threadnumcounter = 0, threadnumlimit = 20;</p><p>  long *aa = &thread

55、numcounter;</p><p>  void main(int argc, char *argv[])</p><p><b>  {</b></p><p>  if(argc != 3)</p><p><b>  {</b></p><p>  cout<

56、<"輸入格式錯誤:scanhost start_ip end_ip"<<endl;</p><p>  getchar();</p><p><b>  }</b></p><p>  if(WSAStartup(MAKEWORD(2,1), &wsadata) != 0)</p>&

57、lt;p><b>  {</b></p><p>  cout<<"WSAStartup failed:"<<GetLastError()<<endl;</p><p>  ExitProcess(STATUS_FAILED);</p><p><b>  }</b&

58、gt;</p><p><b>  //創(chuàng)建原始套接字</b></p><p>  sockraw = WSASocket(AF_INET, SOCK_RAW, IPPROTO_ICMP, NULL, 0, WSA_FLAG_OVERLAPPED);</p><p>  if(sockraw == INVALID_SOCKET)</p&g

59、t;<p><b>  {</b></p><p>  cout<<"WSASocket() failed:"<<WSAGetLastError()<<endl;</p><p>  ExitProcess(STATUS_FAILED);</p><p><b> 

60、 }</b></p><p><b>  //設(shè)置讀取延時</b></p><p>  int timeout = 1000;</p><p>  int bread = setsockopt(sockraw, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout)

61、);</p><p>  if(bread == SOCKET_ERROR)</p><p><b>  {</b></p><p>  cout<<"fail to set recv timeout:"<<WSAGetLastError()<<endl;</p><p

62、>  ExitProcess(STATUS_FAILED);</p><p><b>  }</b></p><p>  timeout = 1000;</p><p>  bread = setsockopt(sockraw, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(ti

63、meout));</p><p>  if(bread == SOCKET_ERROR)</p><p><b>  {</b></p><p>  cout<<"failed to set send timeout:"<<WSAGetLastError()<<endl;</p>

64、;<p>  ExitProcess(STATUS_FAILED);</p><p><b>  }</b></p><p>  memset(&dest, 0, sizeof(dest));</p><p>  unsigned long startip, endip;</p><p>  des

65、t.sin_family = AF_INET;</p><p>  dest.sin_addr.s_addr = inet_addr(argv[1]);</p><p>  startip = inet_addr(argv[1]);</p><p>  end.sin_family = AF_INET;</p><p>  end.sin_a

66、ddr.s_addr = inet_addr(argv[2]);</p><p>  endip = inet_addr(argv[2]);</p><p>  HANDLE hthread;</p><p>  while(htonl(startip) <= htonl(endip))</p><p><b>  {<

67、/b></p><p>  if(threadnumcounter > threadnumlimit)</p><p><b>  {</b></p><p>  Sleep(5000);</p><p><b>  continue;</b></p><p>&

68、lt;b>  }</b></p><p>  DWORD Threadid;</p><p>  sockaddr_in * pipaddrtemp = new(sockaddr_in);</p><p>  if(!pipaddrtemp)</p><p><b>  {</b></p>

69、<p>  cout<<"memory alloc failed"<<endl;</p><p><b>  return;</b></p><p><b>  }</b></p><p>  *pipaddrtemp = dest;</p><p

70、><b>  //創(chuàng)建新線程</b></p><p>  clock_t start;</p><p>  start = clock();</p><p>  hthread = CreateThread(NULL, NULL, FindIp, (LPVOID)pipaddrtemp, NULL, &Threadid);<

71、/p><p>  long i = 60000000L;</p><p>  while(i--)</p><p><b>  ;</b></p><p>  TerminateThread(hthread, 0);</p><p>  InterlockedDecrement(aa);</p&

72、gt;<p>  memset(&from, 0, sizeof(from));</p><p>  startip = htonl(htonl(startip) + 1);</p><p>  dest.sin_addr.s_addr = startip;</p><p><b>  }</b></p>&

73、lt;p>  while(threadnumcounter!=0)</p><p><b>  {</b></p><p>  Sleep(2000);</p><p><b>  return;</b></p><p><b>  }</b></p>&l

74、t;p><b>  }</b></p><p>  void fill_icmp_data(char * icmp_data, int datasize)</p><p><b>  {</b></p><p>  Icmpheader *icmp_hdr;</p><p>  char *d

75、atapart;</p><p>  icmp_hdr = (Icmpheader*)icmp_data;</p><p>  icmp_hdr->type = ICMP_ECHO;</p><p>  icmp_hdr->id = (USHORT)GetCurrentThreadId();</p><p>  datapart

76、= icmp_data + sizeof(Icmpheader);</p><p>  memset(datapart, 'A', datasize - sizeof(Icmpheader));</p><p><b>  }</b></p><p>  void decode_resp(char *buf, int bytes

77、, struct sockaddr_in *from)</p><p><b>  {</b></p><p>  IpHeader *iphdr;</p><p>  Icmpheader *icmphdr;</p><p>  unsigned short iphdrlen;</p><p>

78、  iphdr = (IpHeader *)buf;</p><p>  iphdrlen = iphdr->headlen * 4;</p><p>  icmphdr = (Icmpheader *)(buf + iphdrlen);</p><p>  //數(shù)據(jù)包太短 丟棄</p><p>  if(bytes < iphd

79、rlen + ICMP_MIN) </p><p><b>  return;</b></p><p>  if(icmphdr->type != ICMP_ECHO_REPLY) </p><p><b>  return;</b></p><p>  if(icmphdr

80、->id != (USHORT)GetCurrentThreadId()) </p><p><b>  return;</b></p><p>  cout<<"活動主機(jī)"<<inet_ntoa(from->sin_addr)<<endl;</p><p><b>

81、  }</b></p><p>  USHORT checksum(USHORT *buffer, int size)</p><p><b>  {</b></p><p>  unsigned long cksum = 0;</p><p>  while (size > 1)</p>

82、<p><b>  {</b></p><p>  cksum += *buffer++;</p><p>  size -= sizeof(USHORT);</p><p><b>  }</b></p><p><b>  if(size)</b></p&

83、gt;<p><b>  {</b></p><p>  cksum += *(UCHAR*)buffer;</p><p><b>  }</b></p><p>  cksum = (cksum >> 16) + (cksum & 0xffff);</p><p&g

84、t;  cksum += (cksum >> 16);</p><p>  return (USHORT)(~cksum);</p><p><b>  }</b></p><p>  DWORD WINAPI FindIp(LPVOID pipaddrtemp)</p><p><b>  {&l

85、t;/b></p><p>  InterlockedIncrement(aa);</p><p>  char icmp_data[MAX_PACKET];</p><p>  memset(icmp_data, 0, MAX_PACKET);</p><p>  int datasize = DEF_PACKET_SIZE;<

86、/p><p>  datasize += sizeof(Icmpheader);</p><p>  fill_icmp_data(icmp_data, datasize);</p><p>  ((Icmpheader* )icmp_data)->checksum = 0;</p><p>  ((Icmpheader* )icmp_da

87、ta)->seq = 0;</p><p>  //計算校驗(yàn)和后填入</p><p>  ((Icmpheader* )icmp_data)->checksum = checksum((USHORT* )icmp_data, datasize);</p><p>  int bwrote = sendto(sockraw, icmp_data, data

88、size, 0, (struct sockaddr* )pipaddrtemp, sizeof(dest));</p><p>  int n = 0;</p><p>  if (bwrote == SOCKET_ERROR)</p><p><b>  {</b></p><p>  if(WSAGetLastErr

89、or() == WSAETIMEDOUT)</p><p><b>  {</b></p><p>  cout<<"timed out"<<endl;</p><p><b>  }</b></p><p>  cout<<"sen

90、dto failed: "<<WSAGetLastError()<<endl;</p><p>  ExitProcess(STATUS_FAILED);</p><p><b>  n = 1;</b></p><p><b>  }</b></p><p>  

91、if(bwrote < datasize)</p><p><b>  {</b></p><p>  cout<<"worte "<<bwrote<<" bytes"<<endl;</p><p>  ExitProcess(STATUS_FAILE

92、D);</p><p><b>  n = 1;</b></p><p><b>  }</b></p><p>  int bread = recvfrom(sockraw, recvbuf, MAX_PING_PACKET_SIZE, 0, (struct sockaddr* ) &from, &fro

93、mlen);</p><p>  if(bread == SOCKET_ERROR)</p><p><b>  {</b></p><p>  if(WSAGetLastError() == WSAETIMEDOUT)</p><p><b>  {</b></p><p>

94、;  cout<<"time out"<<endl;</p><p><b>  }</b></p><p>  cout<<"recvform failed:"<<WSAGetLastError()<<endl;</p><p>  ExitP

95、rocess(STATUS_FAILED);</p><p><b>  n = 1;</b></p><p><b>  }</b></p><p>  if(n == 0)</p><p>  decode_resp(recvbuf, bread, &from);</p>

96、<p>  InterlockedDecrement(aa);</p><p><b>  return 0;</b></p><p><b>  }</b></p><p><b>  四、調(diào)試及運(yùn)行結(jié)果</b></p><p><b>  運(yùn)行結(jié)果如以下

97、圖:</b></p><p>  路由器連接2臺電腦結(jié)果截圖:</p><p>  路由器連接1臺電腦結(jié)果截圖:</p><p>  命令格式輸入錯誤結(jié)果截圖:</p><p><b>  五、總結(jié)</b></p><p>  在網(wǎng)絡(luò)管理中,常常要確定當(dāng)前網(wǎng)絡(luò)中處于活動狀態(tài)的主機(jī),通過

98、本次課程設(shè)計,利用C++編程實(shí)現(xiàn)簡單的對網(wǎng)絡(luò)中活動主機(jī)的檢測,設(shè)計中通過使用ICMP的回送和回送響應(yīng)消息來完成這項(xiàng)工作。網(wǎng)際控制報文協(xié)議(ICMP)具有補(bǔ)充IP功能的作用。</p><p>  通過這次課程設(shè)計,我加深了對ICMP協(xié)議的理解,鞏固了課堂知識,為以后學(xué)習(xí)網(wǎng)絡(luò)協(xié)議打下基礎(chǔ)。</p><p>  程序使用原始套接字生成ICMP報文來進(jìn)行活動主機(jī)的探查。程序的大致思想是把ICMP的

99、數(shù)據(jù)包類型設(shè)置為回送請求,將它發(fā)送給網(wǎng)絡(luò)上的一個IP地址,如果這個IP地址已經(jīng)被占用的話,那幺使用位于這個IP地址的主機(jī)上的TCP/IP軟件就能夠接收到這個ICMP回送請求,從而返回一個ICMP回送響應(yīng)(類型號為0)信息。信息封裝在一個IP包中,我們需要解析該IP包,從中找到ICMP數(shù)據(jù)信息。相反,如果這個IP地址沒有人使用,那幺發(fā)送的ICMP回送請求在設(shè)定的延時內(nèi)就不可能得到響應(yīng)。</p><p>  由于網(wǎng)絡(luò)

100、協(xié)議比較抽象,比較難學(xué),也學(xué)得不深入,何況還要把所學(xué)知識運(yùn)用到實(shí)踐中來,真是一大難題,所以一開始時,真是有點(diǎn)一籌莫展,網(wǎng)上查有關(guān)資料卻總覺得不搭干。</p><p>  在調(diào)試過程中難免要出現(xiàn)一些問題,為了能夠快速地確定錯誤的原因,盡快的排除程序邏輯錯誤,通常把程序錯誤劃分為三種類型:語法錯誤、運(yùn)行錯誤和邏輯錯誤。在這次網(wǎng)絡(luò)課程設(shè)計中,也發(fā)生了這樣那樣的錯誤,通過查閱文獻(xiàn)資料、請教老師和同學(xué)討論,以及自己認(rèn)真地分

101、析與思考,逐一對錯誤進(jìn)行了調(diào)試,使程序基本能正常運(yùn)行。</p><p>  到最后只差最后結(jié)果截圖的時候,由于自己的粗心還鬧出了個小烏龍。用路由器連接2臺電腦后,運(yùn)行結(jié)果為網(wǎng)絡(luò)中沒有活動主機(jī),第一反應(yīng)就是程序有問題,于是回過頭又開始糾結(jié)程序的問題。正在苦苦納悶的時候,轉(zhuǎn)頭發(fā)現(xiàn)另外一臺筆記本的瀏覽器并不能打開網(wǎng)頁,這才意識到可能是路由器連接出了問題,于是開始搗鼓路由器,又是重新啟動又是重新設(shè)置路由器,等到折騰一通后

102、,猛然發(fā)現(xiàn)其實(shí)是自己把連接最左側(cè)WAN口的網(wǎng)線插到了最右側(cè)1口中。耽誤了不少時間。</p><p>  通過這次課程設(shè)計,我明白做什么事都要沉得下心,遇到問題沉著冷靜是特別重要的,千萬不能有半點(diǎn)浮躁的心情。并且當(dāng)出現(xiàn)問題后,要仔細(xì)認(rèn)真的去考慮發(fā)現(xiàn)出現(xiàn)問題的最后可能是哪部分,而不是一味的回頭找代碼的問題。在程序的調(diào)試過程中,出現(xiàn)問題是正常的,關(guān)鍵是如何去發(fā)現(xiàn)問題的根源,然后去解決它。其實(shí)寫程序并不是很花時間,改錯才

103、是最花時間的的事情。還有一點(diǎn)特別重要的是,在設(shè)計過程中或者是改錯的過程中遇到棘手的問題時,借助網(wǎng)絡(luò)去解決的確是一種很好的選擇。</p><p><b>  參考文獻(xiàn):</b></p><p>  [1] .吳功宜,胡曉英等著.計算機(jī)網(wǎng)絡(luò)課程設(shè)計.北京:機(jī)械工業(yè)出版社。</p><p>  [2].周明天等,TCP/IP網(wǎng)絡(luò)原理與技術(shù).北京:清華

溫馨提示

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

評論

0/150

提交評論