版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、<p><b> 計(jì)算機(jī)網(wǎng)絡(luò)課程設(shè)計(jì)</b></p><p> 一、設(shè)計(jì)內(nèi)容及設(shè)計(jì)要求</p><p> 1.1課程設(shè)計(jì)內(nèi)容:</p><p> 利用ICMP數(shù)據(jù)包,通過使用ICMP的回送和回送響應(yīng)消息來確定當(dāng)前網(wǎng)絡(luò)中處于活動(dòng)狀態(tài)的主機(jī),即ping消息的請(qǐng)求和應(yīng)答,將發(fā)送的ICMP的數(shù)據(jù)包類型設(shè)置為回送請(qǐng)求(類型號(hào)為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è)計(jì)目的:</p><p> IP協(xié)議的優(yōu)點(diǎn)是簡(jiǎn)單,但缺少差錯(cuò)控制和查詢機(jī)制,而網(wǎng)際控制報(bào)文協(xié)議(ICMP具有補(bǔ)充IP功能的作用。在網(wǎng)絡(luò)管理中,常常要確定當(dāng)前網(wǎng)絡(luò)在
3、紅處于活動(dòng)狀態(tài)的主機(jī),這時(shí)可以通過ICMP的回送和回送響應(yīng)消息來完成這項(xiàng)工作。這課程設(shè)計(jì)的目的就是編制程序,利用ICMP數(shù)據(jù)包,發(fā)現(xiàn)網(wǎng)絡(luò)中的活動(dòng)主機(jī),即ping消息的請(qǐng)求和應(yīng)答。通過課程設(shè)計(jì),熟悉ICMP報(bào)文的結(jié)構(gòu),對(duì)ICMP協(xié)議有更好的理解和認(rèn)識(shí),培養(yǎng)綜合運(yùn)用網(wǎng)絡(luò)知識(shí)解決實(shí)際問題能力。</p><p> 1.3課程設(shè)計(jì)要求:</p><p> 設(shè)計(jì)程序,其功能是發(fā)送ICMP數(shù)據(jù)包,以
4、獲取指定望段中的活動(dòng)主機(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> 活動(dòng)主機(jī)1的IP地址</p><p> 活動(dòng)主機(jī)2的IP地址</p><p> 活動(dòng)主機(jī) n的IP地址</p><p><b> 二、總體設(shè)計(jì)</b></p><p><b> 2.1設(shè)計(jì)原理&l
6、t;/b></p><p> 首先對(duì)ICMP報(bào)文的格式有一定的了解,ICMP報(bào)文是在IP數(shù)據(jù)報(bào)內(nèi)部傳輸?shù)?,其結(jié)構(gòu)如圖所示:</p><p><b> IP數(shù)據(jù)報(bào)</b></p><p> IP首部 ICMP報(bào)文</p><p> ICMP報(bào)文的格式如圖所示:</p><p>
7、; 0 7 8 15 16 31(位)</p><p> 所有報(bào)文的前4個(gè)字節(jié)都是一樣的,但是其它字節(jié)則互不相同。其中類型字段可以有15個(gè)不同的值,以描述特定類型的ICMP報(bào)文,某些ICMP報(bào)文還使用代碼字段的值來進(jìn)一步描述不用的條件。按驗(yàn)和字段為2字節(jié),校驗(yàn)的范圍是整個(gè)ICMP報(bào)文。檢驗(yàn)和是必須的,其計(jì)算方法與I
8、P協(xié)議頭部校驗(yàn)和的計(jì)算方法一樣。</p><p> 各種類型的ICMP報(bào)文如圖所示(ICMP報(bào)文類型),不同類型由報(bào)文中的類型字段和代碼字段來共同決定。</p><p> 課程設(shè)計(jì)的目的是發(fā)現(xiàn)網(wǎng)絡(luò)中的活動(dòng)主機(jī),就是使用ICMP的回送和回送響應(yīng)消息發(fā)現(xiàn)網(wǎng)絡(luò)中的活動(dòng)主機(jī),即Ping消息的請(qǐng)求和應(yīng)答。那幺,發(fā)送的ICMP的數(shù)據(jù)包類型設(shè)置為回送請(qǐng)求(類型號(hào)為8)。</p><
9、;p> 本程序使用的原始套接字生成ICMP請(qǐng)求/應(yīng)答報(bào)文來進(jìn)行活動(dòng)主機(jī)的探查。這個(gè)程序使用的是回送請(qǐng)求和應(yīng)答消息。程序的大致思想是把ICMP的數(shù)據(jù)報(bào)類型設(shè)置為回送請(qǐng)求,將它發(fā)送給網(wǎng)絡(luò)上的一個(gè)IP地址,如果這個(gè)IP地址已經(jīng)被占用的話,那么使用位于這個(gè)IP地址的主機(jī)上的TCP/IP軟件就能接受到這個(gè)ICMP回送請(qǐng)求,從而返回一個(gè)ICMP回送請(qǐng)求(類型號(hào)為0)信息。信息封裝在一個(gè)IP包中,我們需要解析該IP包,從中找到ICMP數(shù)據(jù)信息
10、,相反,如果這個(gè)IP地址沒有人使用,那么發(fā)送的ICMP回送請(qǐng)求在設(shè)定的延時(shí)內(nèi)就不可能得到響應(yīng)。</p><p><b> 2.2概要設(shè)計(jì)</b></p><p><b> 主程序流程圖</b></p><p><b> 子線程流程圖</b></p><p><b&g
11、t; 三、詳細(xì)設(shè)計(jì)及代碼</b></p><p> 3.1 ICMP報(bào)文分析</p><p> ICMP是一種差錯(cuò)和控制報(bào)文協(xié)議,用于傳輸錯(cuò)誤報(bào)告和控制信息。</p><p> ICMP報(bào)文分為頭部和數(shù)據(jù)部分。ICMP報(bào)文封裝在IP數(shù)據(jù)報(bào)中傳輸。IP報(bào)頭中的類型為1時(shí),表示報(bào)文的數(shù)據(jù)部分為ICMP報(bào)文。雖然ICMP報(bào)文由IP報(bào)文傳輸,但是并不能認(rèn)
12、為ICMP是IP的上層協(xié)議,而是IP協(xié)議的有機(jī)補(bǔ)充。把ICMP報(bào)文放在IP包中,是要利用IP的轉(zhuǎn)發(fā)功能。</p><p> 類型(TYPE)是一個(gè)字節(jié),表示ICMP消息的類型。代碼(CODE)也是一個(gè)字節(jié),表示報(bào)文類型的下一步信息。校驗(yàn)和共有兩個(gè)字節(jié),提供對(duì)整個(gè)ICMP報(bào)文的校驗(yàn)和(和IP報(bào)文類型的進(jìn)一步信息)。校驗(yàn)和共兩個(gè)字節(jié),提供對(duì)整個(gè)ICMP報(bào)文的校驗(yàn)和。按照協(xié)議的功能來分,ICMP報(bào)文可以分為</
13、p><p> [1]. ICMP差錯(cuò)報(bào)文 </p><p> 包括目的不可達(dá)報(bào)告,超時(shí)報(bào)告,參數(shù)出錯(cuò)報(bào)告。</p><p> [2] .ICMP控制報(bào)文</p><p> 包括擁塞控制和源抑制報(bào)文,路游控制和重定向報(bào)文</p><p> [3] .ICMP測(cè)試報(bào)文</p><p> 包括
14、請(qǐng)求應(yīng)答報(bào)文,時(shí)戳請(qǐng)求應(yīng)答報(bào)文。</p><p> 本課程設(shè)計(jì)就是使用ICMP請(qǐng)求/應(yīng)答報(bào)文來測(cè)試目的主機(jī)是否存在,請(qǐng)求者想某特定的主機(jī)發(fā)送請(qǐng)求,其中包含任選的數(shù)據(jù)。目的主機(jī)收到請(qǐng)求后,發(fā)送應(yīng)答報(bào)文。在同一時(shí)刻,一臺(tái)機(jī)器可以同時(shí)向多臺(tái)主機(jī)發(fā)送請(qǐng)求報(bào)文。ICMP報(bào)文格式如圖所示:</p><p> ICMP回送報(bào)文格式如下圖所示:</p><p><b>
15、; 3.2程序功能分析</b></p><p> 本程序使用原始套接字生成ICMP報(bào)文來進(jìn)行活動(dòng)主機(jī)的探查。這個(gè)程序使用的是回送請(qǐng)求與應(yīng)答信息。程序的大致思想是把ICMP的數(shù)據(jù)包類型設(shè)置為回送請(qǐng)求,將它發(fā)送給網(wǎng)絡(luò)上的一個(gè)IP地址,如果這個(gè)IP地址已經(jīng)被占用的話,那么使用位于這個(gè)IP地址的主機(jī)上的TCP/IP軟件就能夠接受到這個(gè)ICMP回送請(qǐng)求,從而返回一個(gè)ICMP回送響應(yīng)(類型號(hào)為0)信息。信息封
16、裝在一個(gè)IP包中,需要解析該IP包,從中找到ICMP數(shù)據(jù)信息。相反,如果這個(gè)IP地址沒有人使用,那么發(fā)送的ICMP回送請(qǐng)求在設(shè)定的延時(shí)內(nèi)就不可能得到響應(yīng)。</p><p> 在初始化原始套接字之后,本程序就要開始在一個(gè)IP網(wǎng)段內(nèi)尋找活動(dòng)主機(jī)。因?yàn)橐獙ふ一顒?dòng)的主機(jī)可能很多,為節(jié)省時(shí)間可以采用多線程編程。結(jié)合核心代碼對(duì)程序的具體進(jìn)行分析。</p><p> 3.2.1使用原始套接字<
17、/p><p> 為了實(shí)現(xiàn)發(fā)送/監(jiān)聽I(yíng)CMP抱文,必須使用原始套接字,創(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è)置(設(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í)設(shè)置,SOSNDTIMEO表示使用發(fā)送超時(shí)設(shè)置,在這里
19、,超時(shí)時(shí)間均設(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頭長(zhǎng)度</p><p> unsigned int wersion:4; //ip版本號(hào)</p&
20、gt;<p> unsigned char tos; //服務(wù)類型</p><p> unsigned short totallen; //ip包總長(zhǎng)度</p><p> unsigned short id; //ip號(hào)</p><p> unsigned short flag; //標(biāo)記<
21、/p><p> unsigned char ttl; //生存時(shí)間</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類型碼,回送請(qǐng)求的類型碼為8</p><p> BYTE code; //子類型碼,保存與特定ICMP報(bào)文類型相關(guān)的細(xì)節(jié)信息</p><p> USHORT checksum; //校驗(yàn)和</p><p> USHORT id; //ICMP報(bào)文id號(hào)</p><p> USHORT se
24、q; //ICMP數(shù)據(jù)報(bào)的序列號(hào)</p><p> }Icmpheader;</p><p> 3.2.4填充并發(fā)送請(qǐng)求類型的ICMP報(bào)文</p><p> #define ICMP_ECHO 8 //請(qǐng)求回送</p><p> #define DEF_PACKET_SIZE 32 //缺省數(shù)據(jù)
25、報(bào)長(zhǎng)度</p><p> #define MAX_PACKET 1024 //最大數(shù)據(jù)報(bào)長(zhǎng)度</p><p> #char icmp_data[MAX_PACKET]; //ICMP數(shù)據(jù)報(bào)最大可能長(zhǎng)度</p><p> Memset(icmp_data,0, MAX_PACKET) //將數(shù)據(jù)報(bào)清空初始化</p><p>
26、Int datasize=DEF_PACKET_SIZE; //ICMP數(shù)據(jù)報(bào)報(bào)文體的額缺省長(zhǎng)度</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號(hào)為當(dāng)前線程號(hào)</p><p> datapart=icmp_
28、data+sizeof(icmpheader); //計(jì)算出ICMP數(shù)據(jù)報(bào)的數(shù)據(jù)部分</p><p> memset(datapart,'A',datasize-sizeof(icmphearder)); //填入數(shù)據(jù)</p><p> ((IcmpHeader*)icmp_data)->seq=0; //序列號(hào)</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 為計(jì)算校驗(yàn)和的函數(shù),設(shè)校驗(yàn)和初值為0,然后對(duì)數(shù)據(jù)每1
30、6位求異或,結(jié)果取反,便得校驗(yàn)和。其代碼如下:</p><p> USHORT checksum(USHORT * buffer, int size) //計(jì)算校驗(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報(bào)文之后,應(yīng)在ICMP報(bào)文之前加上IP報(bào)頭并發(fā)送出去??烧{(diào)用下面的代碼發(fā)送數(shù)據(jù)包。注意,這里的dest是填入目的主機(jī)的IP地址的一個(gè)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ī)存在,那么它會(huì)發(fā)出一個(gè)回送應(yīng)答包。這是一個(gè)IP包,受到后解析此數(shù)據(jù)包并獲得其中的ICMP信息。根據(jù)IP報(bào)頭信息中的IP報(bào)頭長(zhǎng)度字段,就可以得到ICMP報(bào)文的真實(shí)
36、地址。ICMP數(shù)據(jù)包中的IP地址就是活動(dòng)主機(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報(bào)頭的長(zhǎng)度</p><p> icmphdr=(icmpheader *)(buf+iphdrlen); //跳過IP頭</p><p> //數(shù)據(jù)包太短 丟棄</p><p> if(bytes<iphdrlen+icmp_min) return; //不是回送請(qǐng)求(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;<"活動(dòng)主機(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頭長(zhǎng)度</p><p> unsigned int wersion:4; //ip版本號(hào)</p><p> unsigned char tos; //服務(wù)類型</p>
45、<p> unsigned short totallen; //ip包總長(zhǎng)度</p><p> unsigned short id; //ip號(hào)</p><p> unsigned short flag; //標(biāo)記</p><p> unsigned char ttl; //生存時(shí)間</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類型碼,回送請(qǐng)求的類型碼為8</p><p> BYTE code;
48、 //子類型碼,保存與特定ICMP報(bào)文類型相關(guān)的</p><p><b> //節(jié)信息</b></p><p> USHORT checksum; //校驗(yàn)和</p><p> USHORT id; //ICMP報(bào)文id號(hào)</p><p> USHORT seq
49、; //ICMP數(shù)據(jù)報(bào)的序列號(hào)</p><p> }Icmpheader;</p><p> #define ICMP_ECHO 8 //請(qǐng)求回送</p><p> #define ICMP_ECHO_REPLY 0 //請(qǐng)求回應(yīng)</p><p> #define ICMP_MIN 8
50、 //ICMP包頭長(zhǎng)度(最小ICMP包長(zhǎng)度)</p><p> #define STATUS_FAILED 0xFFFF //錯(cuò)誤碼</p><p> #define DEF_PACKET_SIZE 32 //缺省數(shù)據(jù)報(bào)長(zhǎng)度</p><p> #define MAX_PACKET 1024 //最大數(shù)據(jù)報(bào)長(zhǎng)度</p><
51、p> #define MAX_PING_PACKET_SIZE (MAX_PACKET + sizeof(IpHeader)) //最大接受數(shù)據(jù)報(bào)長(zhǎng)度</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ù)報(bào)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、<"輸入格式錯(cuò)誤: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è)置讀取延時(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<<"活動(dòng)主機(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> //計(jì)算校驗(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臺(tái)電腦結(jié)果截圖:</p><p> 路由器連接1臺(tái)電腦結(jié)果截圖:</p><p> 命令格式輸入錯(cuò)誤結(jié)果截圖:</p><p><b> 五、總結(jié)</b></p><p> 在網(wǎng)絡(luò)管理中,常常要確定當(dāng)前網(wǎng)絡(luò)中處于活動(dòng)狀態(tài)的主機(jī),通過
98、本次課程設(shè)計(jì),利用C++編程實(shí)現(xiàn)簡(jiǎn)單的對(duì)網(wǎng)絡(luò)中活動(dòng)主機(jī)的檢測(cè),設(shè)計(jì)中通過使用ICMP的回送和回送響應(yīng)消息來完成這項(xiàng)工作。網(wǎng)際控制報(bào)文協(xié)議(ICMP)具有補(bǔ)充IP功能的作用。</p><p> 通過這次課程設(shè)計(jì),我加深了對(duì)ICMP協(xié)議的理解,鞏固了課堂知識(shí),為以后學(xué)習(xí)網(wǎng)絡(luò)協(xié)議打下基礎(chǔ)。</p><p> 程序使用原始套接字生成ICMP報(bào)文來進(jìn)行活動(dòng)主機(jī)的探查。程序的大致思想是把ICMP的
99、數(shù)據(jù)包類型設(shè)置為回送請(qǐng)求,將它發(fā)送給網(wǎng)絡(luò)上的一個(gè)IP地址,如果這個(gè)IP地址已經(jīng)被占用的話,那幺使用位于這個(gè)IP地址的主機(jī)上的TCP/IP軟件就能夠接收到這個(gè)ICMP回送請(qǐng)求,從而返回一個(gè)ICMP回送響應(yīng)(類型號(hào)為0)信息。信息封裝在一個(gè)IP包中,我們需要解析該IP包,從中找到ICMP數(shù)據(jù)信息。相反,如果這個(gè)IP地址沒有人使用,那幺發(fā)送的ICMP回送請(qǐng)求在設(shè)定的延時(shí)內(nèi)就不可能得到響應(yīng)。</p><p> 由于網(wǎng)絡(luò)
100、協(xié)議比較抽象,比較難學(xué),也學(xué)得不深入,何況還要把所學(xué)知識(shí)運(yùn)用到實(shí)踐中來,真是一大難題,所以一開始時(shí),真是有點(diǎn)一籌莫展,網(wǎng)上查有關(guān)資料卻總覺得不搭干。</p><p> 在調(diào)試過程中難免要出現(xiàn)一些問題,為了能夠快速地確定錯(cuò)誤的原因,盡快的排除程序邏輯錯(cuò)誤,通常把程序錯(cuò)誤劃分為三種類型:語法錯(cuò)誤、運(yùn)行錯(cuò)誤和邏輯錯(cuò)誤。在這次網(wǎng)絡(luò)課程設(shè)計(jì)中,也發(fā)生了這樣那樣的錯(cuò)誤,通過查閱文獻(xiàn)資料、請(qǐng)教老師和同學(xué)討論,以及自己認(rèn)真地分
101、析與思考,逐一對(duì)錯(cuò)誤進(jìn)行了調(diào)試,使程序基本能正常運(yùn)行。</p><p> 到最后只差最后結(jié)果截圖的時(shí)候,由于自己的粗心還鬧出了個(gè)小烏龍。用路由器連接2臺(tái)電腦后,運(yùn)行結(jié)果為網(wǎng)絡(luò)中沒有活動(dòng)主機(jī),第一反應(yīng)就是程序有問題,于是回過頭又開始糾結(jié)程序的問題。正在苦苦納悶的時(shí)候,轉(zhuǎn)頭發(fā)現(xiàn)另外一臺(tái)筆記本的瀏覽器并不能打開網(wǎng)頁,這才意識(shí)到可能是路由器連接出了問題,于是開始搗鼓路由器,又是重新啟動(dòng)又是重新設(shè)置路由器,等到折騰一通后
102、,猛然發(fā)現(xiàn)其實(shí)是自己把連接最左側(cè)WAN口的網(wǎng)線插到了最右側(cè)1口中。耽誤了不少時(shí)間。</p><p> 通過這次課程設(shè)計(jì),我明白做什么事都要沉得下心,遇到問題沉著冷靜是特別重要的,千萬不能有半點(diǎn)浮躁的心情。并且當(dāng)出現(xiàn)問題后,要仔細(xì)認(rèn)真的去考慮發(fā)現(xiàn)出現(xiàn)問題的最后可能是哪部分,而不是一味的回頭找代碼的問題。在程序的調(diào)試過程中,出現(xiàn)問題是正常的,關(guān)鍵是如何去發(fā)現(xiàn)問題的根源,然后去解決它。其實(shí)寫程序并不是很花時(shí)間,改錯(cuò)才
103、是最花時(shí)間的的事情。還有一點(diǎn)特別重要的是,在設(shè)計(jì)過程中或者是改錯(cuò)的過程中遇到棘手的問題時(shí),借助網(wǎng)絡(luò)去解決的確是一種很好的選擇。</p><p><b> 參考文獻(xiàn):</b></p><p> [1] .吳功宜,胡曉英等著.計(jì)算機(jī)網(wǎng)絡(luò)課程設(shè)計(jì).北京:機(jī)械工業(yè)出版社。</p><p> [2].周明天等,TCP/IP網(wǎng)絡(luò)原理與技術(shù).北京:清華
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 眾賞文庫僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 計(jì)算機(jī)網(wǎng)絡(luò)課程設(shè)計(jì)
- 計(jì)算機(jī)網(wǎng)絡(luò)課程設(shè)計(jì)
- 計(jì)算機(jī)網(wǎng)絡(luò)課程設(shè)計(jì)
- 《計(jì)算機(jī)網(wǎng)絡(luò)課程設(shè)計(jì)》
- 計(jì)算機(jī)網(wǎng)絡(luò)課程設(shè)計(jì)---網(wǎng)絡(luò)設(shè)計(jì)
- 計(jì)算機(jī)網(wǎng)絡(luò)課程設(shè)計(jì)
- 計(jì)算機(jī)網(wǎng)絡(luò)課程設(shè)計(jì)
- 計(jì)算機(jī)網(wǎng)絡(luò)課程設(shè)計(jì)
- 計(jì)算機(jī)網(wǎng)絡(luò)課程設(shè)計(jì)
- 計(jì)算機(jī)網(wǎng)絡(luò)課程設(shè)計(jì)-- 小型網(wǎng)絡(luò)設(shè)計(jì)
- 計(jì)算機(jī)網(wǎng)絡(luò)課程設(shè)計(jì)--網(wǎng)絡(luò)互聯(lián)設(shè)計(jì)
- 計(jì)算機(jī)網(wǎng)絡(luò)課程設(shè)計(jì)報(bào)告
- 計(jì)算機(jī)網(wǎng)絡(luò)課程設(shè)計(jì)報(bào)告
- 計(jì)算機(jī)網(wǎng)絡(luò)課程設(shè)計(jì)報(bào)告
- 計(jì)算機(jī)網(wǎng)絡(luò)組建課程設(shè)計(jì)
- 計(jì)算機(jī)網(wǎng)絡(luò)課程設(shè)計(jì)報(bào)告
- 《計(jì)算機(jī)網(wǎng)絡(luò)》課程設(shè)計(jì)報(bào)告
- 計(jì)算機(jī)網(wǎng)絡(luò)課程設(shè)計(jì)報(bào)告
- 計(jì)算機(jī)網(wǎng)絡(luò)課程設(shè)計(jì)報(bào)告
- 《計(jì)算機(jī)網(wǎng)絡(luò)》課程設(shè)計(jì)報(bào)告
評(píng)論
0/150
提交評(píng)論