版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、<p><b> 課程設(shè)計(jì)實(shí)驗(yàn)報(bào)告</b></p><p> 專 業(yè): 12級(jí)通信工程(2)班 </p><p> 學(xué) 號(hào): </p><p> 姓 名: </p><p> 實(shí)驗(yàn)所屬課程:通信網(wǎng)綜合課程設(shè)計(jì)</
2、p><p> 一、程設(shè)計(jì)的目的和意義</p><p> 在網(wǎng)絡(luò)管理中,經(jīng)常要確定當(dāng)前網(wǎng)絡(luò)中處于活動(dòng)狀態(tài)的主機(jī),這時(shí)可以通過使用 ICMP協(xié)議的回送請(qǐng)求(Ping請(qǐng)求)和回送響應(yīng)(Ping應(yīng)答)消息來完成本工作。</p><p> 本課程設(shè)計(jì)的目的是編制程序,利用ICMP數(shù)據(jù)包,發(fā)現(xiàn)制定網(wǎng)段中的活動(dòng)主機(jī)。</p><p> IP協(xié)議的優(yōu)點(diǎn)是
3、簡(jiǎn)潔,但缺少差錯(cuò)控制和查詢機(jī)制,而網(wǎng)際控制報(bào)文協(xié)議(ICMP)具有補(bǔ)充IP功能的作用。在網(wǎng)絡(luò)管理中,常常要確定當(dāng)前網(wǎng)絡(luò)中處于活動(dòng)狀態(tài)的主機(jī),這時(shí)可以通過使用ICMP的回送和回送響應(yīng)消息來完成這項(xiàng)工作。本課程設(shè)計(jì)的目的就是編制程序,利用ICMP數(shù)據(jù)包,發(fā)現(xiàn)指定網(wǎng)段中的活動(dòng)主機(jī)。通過課程設(shè)計(jì),使學(xué)生更加熟悉ICMP報(bào)文的結(jié)構(gòu),對(duì)ICMP協(xié)議有更好的理解和認(rèn)識(shí)。</p><p><b> 二、課程設(shè)計(jì)條件&
4、lt;/b></p><p> 計(jì)算機(jī),Matlab、C/C++或JAVA編程軟件或者其他通信網(wǎng)仿真軟件(如NS2、OMNET++等)、嵌入式開發(fā)板、編程器等。</p><p> 三、程設(shè)計(jì)的內(nèi)容和要求</p><p> 本程序的功能是發(fā)送ICMP數(shù)據(jù)包,以獲取指定網(wǎng)段中的活動(dòng)主機(jī),并將結(jié)果顯示到屏幕上。</p><p><
5、b> 程序的要求</b></p><p> 1) 不允許在程序中直接調(diào)用Ping,而是用程序?qū)崿F(xiàn)Ping的功能。</p><p> 2) 以命令形式運(yùn)行:程序名 Start_ip End_ip, 其中,Start_IP為起始IP地址;End_IP為結(jié)束IP地址。</p><p><b> 3) 輸出格式為:</b>&
6、lt;/p><p> 活動(dòng)主機(jī)1的IP地址</p><p> 活動(dòng)主機(jī)2的IP地址</p><p><b> ……</b></p><p> 四、課程設(shè)計(jì)的相關(guān)技術(shù)</p><p> IP 協(xié)議是一種不可靠的協(xié)議,無法進(jìn)行差錯(cuò)控制。但I(xiàn)P 協(xié)議可以借助其他協(xié)議來實(shí)現(xiàn)這一功能,</p&g
7、t;<p> 如ICMP。ICMP(Internet Control Messages Protocol, 網(wǎng)間控制報(bào)文協(xié)議)允許主機(jī)或路由器報(bào)告差錯(cuò)情況和提供有關(guān)異常情況的報(bào)告。一般來說,ICMP 報(bào)文提供針對(duì)網(wǎng)絡(luò)層的錯(cuò)誤診斷、擁塞控制、路徑控制和查詢服務(wù)四項(xiàng)大的功能。如,當(dāng)一個(gè)分組無法到達(dá)目的站點(diǎn)或TTL 超時(shí)后,路由器就會(huì)丟棄此分組,并向源站點(diǎn)返回一個(gè)目的站點(diǎn)不可到達(dá)的ICMP 報(bào)文。</p><
8、;p> 編制程序前首先要對(duì)ICMP報(bào)文的格式有一定的了解,ICMP報(bào)文是在IP數(shù)據(jù)報(bào)內(nèi)部傳輸?shù)?,其結(jié)構(gòu)如圖10-1所示。</p><p><b> IP數(shù)據(jù)報(bào)</b></p><p> IP首部 ICMP報(bào)文</p><p> 圖10-1 ICMP封裝在IP內(nèi)部</p><p&
9、gt; 0 7 8 15 16 31(位)</p><p> 圖10-2 ICMP報(bào)文</p><p> ICMP報(bào)文的格式如圖10-2所示。所有報(bào)文的前4個(gè)字節(jié)都是一樣的,但是其它字節(jié)則互不相同。其中類型字段可以有15個(gè)不同的值,以描述特定類型的ICMP報(bào)文,某些ICMP報(bào)文還使
10、用代碼字段的值來進(jìn)一步描述不用的條件。按驗(yàn)和字段為2字節(jié),校驗(yàn)的范圍是整個(gè)ICMP報(bào)文。檢驗(yàn)和是必須的,其計(jì)算方法與IP協(xié)議頭部校驗(yàn)和的計(jì)算方法一樣。</p><p> 各種類型的ICMP報(bào)文如圖10-3所示(ICMP報(bào)文類型),不同類型由報(bào)文中的類型字段和代碼字段來共同決定。</p><p> 10-3 ICMP報(bào)文類型</p><p> 本課程設(shè)計(jì)的目的
11、是發(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><p><b> 五、課程設(shè)計(jì)過程</b></p><p> 本程序使用原始套接字(SOCK_RAW)生成ICMP報(bào)文來進(jìn)行活動(dòng)主機(jī)的探查,這個(gè)程序使用的是回送請(qǐng)求與應(yīng)答信息。<
12、/p><p> 程序的大致思想:把ICMP的數(shù)據(jù)包類型設(shè)置為回送請(qǐng)求(Ping請(qǐng)求,類型號(hào)為8),將它發(fā)送給網(wǎng)絡(luò)上的一個(gè)IP地址,如果這個(gè)IP地址已經(jīng)被占用,那么使用該IP地址的主機(jī)的,從而返回一個(gè)ICMP回送響應(yīng)(類型號(hào)為0)的信息。信息封裝在一個(gè)IP包中,需要解析該IP包,找到ICMP數(shù)據(jù)信息(類型為0,表示為對(duì)方的應(yīng)答,證明對(duì)方IP地址是活動(dòng)的),如果這個(gè)IP地址沒有人使用,則發(fā)送的ICMP回送請(qǐng)求(Ping
13、請(qǐng)求)在設(shè)定的延時(shí)時(shí)間內(nèi)不可能得到響應(yīng)。</p><p> 初始化原始套接字后(SOCK_RAW)后,本程序就開始在一個(gè)IP網(wǎng)段內(nèi)尋找活動(dòng)主機(jī),由于要尋找的主機(jī)較多,可以采用多線程技術(shù)</p><p> 4.1、分析ICMP協(xié)議類型和程序?qū)崿F(xiàn)方法</p><p> 創(chuàng)建ICMP數(shù)據(jù)報(bào)的內(nèi)容格式,把ICMP的數(shù)據(jù)包類型設(shè)置為回送請(qǐng)求(Ping請(qǐng)求,類型號(hào)為8)。
14、具體實(shí)現(xiàn)代碼如下:</p><p> //IP報(bào)頭的數(shù)據(jù)結(jié)構(gòu)</p><p> typedef struct iphdr{</p><p> unsigned int headlen:4; //IP頭長(zhǎng)度</p><p> unsigned int version:4;
15、//IP版本號(hào)</p><p> unsigned char tos; //服務(wù)類型</p><p> unsigned short totallen; //IP包總長(zhǎng)度</p><p> unsigned short id;; //ID號(hào)</
16、p><p> unsigned short flag; //標(biāo)記</p><p> unsigned char ttl; //生存時(shí)間</p><p> unsigned char prot; //協(xié)議(UDP TCP)</p>&
17、lt;p> unsigned short checksum; //校驗(yàn)和</p><p> unsigned int sourceIP; //源IP</p><p> unsigned int destIP; //目的IP</p><p> }IpHe
18、ader;</p><p> //ICMP頭部的數(shù)據(jù)結(jié)構(gòu)</p><p> typedef struct icmphdr{</p><p> BYTE type; //ICMP類型碼,回送請(qǐng)求的類型碼為8</p><p> BYTE code; //子類型碼,保存與特定ICMP報(bào)文類
19、型相關(guān)細(xì)節(jié)信息</p><p> USHORT checksum; //校驗(yàn)和</p><p> USHORT id; //ICMP報(bào)文ID號(hào)(一般用進(jìn)程號(hào)作ID)</p><p> USHORT seg; //ICMP數(shù)據(jù)報(bào)的序列號(hào)</p><
20、p> }IcmpHeader;</p><p> WSAStartup函數(shù)</p><p> 本函數(shù)必須是應(yīng)用程序或DLL調(diào)用的第一個(gè)Windows Sockets函數(shù).它允許應(yīng)用程序或DLL指明Windows Sockets API的版本號(hào)及獲得特定Windows Sockets實(shí)現(xiàn)的細(xì)節(jié).應(yīng)用程序或DLL只能在一次成功的WSAStartup()調(diào)用之后才能調(diào)用進(jìn)一步的Win
21、dows Sockets API函數(shù)。具體應(yīng)用:</p><p> MAKEWORD函數(shù)</p><p> 本函數(shù)用于進(jìn)行對(duì)Socket版本的指定和協(xié)商,具體應(yīng)用實(shí)例如下:</p><p> 4.2、實(shí)例化ICMP數(shù)據(jù)報(bào)格式并創(chuàng)建Socket套接字</p><p> 程序使用原始套接字(SOCK_RAW)生成ICMP報(bào)文來進(jìn)行活動(dòng)主機(jī)
22、的探查,這個(gè)程序使用的是回送請(qǐng)求與應(yīng)答信息。具體實(shí)現(xiàn)代碼如下:#define ICMP_RCHO 8 //請(qǐng)求回送</p><p> #define DEF_PACKET_SIZE 32 //缺省數(shù)據(jù)報(bào)長(zhǎng)度</p><p> #define MAX_PACKET 1024 //最大數(shù)據(jù)塊長(zhǎng)度</p&g
23、t;<p> #define ICMP_MIN 8 //ICMP報(bào)文頭長(zhǎng)度(最小ICMP報(bào)文長(zhǎng)度)</p><p> #define ICMP_RCHO_REPLY 0</p><p> #define STATUS_FAILED 0xFFFF</p><p> #define MAX_PING_PACKET_SIZE (MA
24、X_PACKET+sizeof(IpHeader))</p><p> void fill_icmp_data(char *,int);</p><p> USHORT checksum(USHORT *,int);</p><p> void decode_resp(char *,int,struct sockaddr_in *);</p>&
25、lt;p> DWORD WINAPI FindIP(LPVOID pIPAddrTemp);</p><p> WSADATA wsaData;</p><p> SOCKET sockRaw;//為了實(shí)現(xiàn)發(fā)送/監(jiān)聽I(yíng)CMP報(bào)文,必須使用原始套接字,創(chuàng)建原始套接字</p><p> struct sockaddr_in dest,from,end;&l
26、t;/p><p> int fromlen =sizeof(from);//from是一個(gè)sockaddr_in數(shù)據(jù)結(jié)構(gòu),用于保存響應(yīng)的目的的主機(jī)的地址</p><p> char *recvbuf=new char[MAX_PING_PACKET_SIZE];//保證大與發(fā)送包的大小</p><p> 4.3、創(chuàng)建多個(gè)線程</p><p>
27、; 線程是進(jìn)程內(nèi)部的一個(gè)執(zhí)行單元。系統(tǒng)創(chuàng)建好進(jìn)程后,實(shí)際上就啟動(dòng)執(zhí)行了該進(jìn)程的主執(zhí)行線程,主執(zhí)行線程以函數(shù)地址形式,比如說main或WinMain函數(shù),將程序的啟動(dòng)點(diǎn)提供給Windows系統(tǒng)。主執(zhí)行線程終止了,進(jìn)程也就隨之終止。由于要尋找的主機(jī)較多,可以采用多線程技術(shù)( 多線程的函數(shù)為:CreateThread() )。具體實(shí)現(xiàn)代碼如下:</p><p> int fromlen =sizeof(from);
28、//from是一個(gè)sockaddr_in數(shù)據(jù)結(jié)構(gòu),用于保存響應(yīng)的目的的主機(jī)的地址</p><p> char *recvbuf=new char[MAX_PING_PACKET_SIZE];//保證大與發(fā)送包的大小</p><p> unsigned int addr=0;</p><p> long ThreadNumCounter=0,ThreadNumL
29、imit=20;</p><p> long *aa=&ThreadNumCounter;</p><p> void main(int argc,char *argv[])</p><p><b> {</b></p><p> if(WSAStartup(MAKEWORD(2,1),&wsaD
30、ata)!=0)</p><p><b> {</b></p><p> cout<<"WASStartup failed"<<GetLastError()<<endl;</p><p> ExitProcess(STATUS_FAILED);</p><p>
31、;<b> }</b></p><p> sockRaw=WSASocket(AF_INET,SOCK_RAW,IPPROTO_ICMP,NULL,0,WSA_FLAG_OVERLAPPED;</p><p><b> 4.4、解析數(shù)據(jù)包</b></p><p> 如果所Ping的目的主機(jī)所在,那么它會(huì)發(fā)送一個(gè)回送
32、應(yīng)答包。這是一個(gè)IP包,收到后解析此數(shù)據(jù)包并獲取其中的ICMP信息。根據(jù)IP報(bào)頭信息中的IP報(bào)頭長(zhǎng)度字段,就可以得到ICMP報(bào)文的真實(shí)地址。ICMP數(shù)據(jù)包中的IP地址就是活動(dòng)主機(jī)的IP。代碼如下:</p><p> #define ICMP_MIN 8 //ICMP報(bào)文頭長(zhǎng)度(最小ICMP報(bào)文長(zhǎng)度)</p><p> #define MAX_PING_PACKET_S
33、IZE (MAX_PACKET + SIZEOF(IPHeader))</p><p> char *recvbuf=new char[MAX_PING_PACKET_SIZE]; //保證大與發(fā)送包的大小</p><p> //from是一個(gè)sockaddr_in數(shù)據(jù)結(jié)構(gòu),用于保存響應(yīng)的目的的主機(jī)的地址</p><p> struct sockaddr_
34、in from;</p><p> int fromlen = sizeof(from);</p><p> int bytes = recvfrom(sockRaw,recvbuf,MAX_PACKET,0,(strucksockaddr*</p><p> )& from),&fromlen);</p><p>
35、IpHeader *iphdr;</p><p> IcmpHeader *icmphdr;</p><p> unsigned short iphdrlen;</p><p> iphdr=(Ipheader *)buf;</p><p> iphdrlen = iphdr->headlen*4 ; //I
36、P報(bào)頭的長(zhǎng)度</p><p> icmphdr=(Icmpheader *)(buf+iphdrlen); //跳過IP報(bào)頭</p><p> //數(shù)據(jù)包太短,丟棄</p><p> if(bytes<iphdrlen+ICMP_MIN) return;</p><p> //不是回送響應(yīng)(Ping應(yīng)答),丟棄</p&
37、gt;<p> if(icmphdr->type !=ICMP_ECHO_REPLY) return;</p><p> //Id號(hào)不相符,丟棄</p><p> if(icmphdr->id!=(USHOT)GetCurrentThreadId()) return;</p><p> //輸出正在使用的IP地址。</p>
38、;<p> Cout<<”活動(dòng)主機(jī):”<<inet_ntoa(from->sin_addr)<<endl;</p><p><b> 4.5、程序流程圖</b></p><p> 一個(gè)用多線程實(shí)現(xiàn)的程序在課程設(shè)計(jì)過程的第三部分中給出,以下分別是主程序流程圖和子程序流程圖:</p><p&
39、gt;<b> N</b></p><p> Y Y</p><p><b> N</b></p><p><b> Y </b></p><p><b> N</b></p><p>&
40、lt;b> 圖1 主程序流程圖</b></p><p><b> Y</b></p><p><b> N</b></p><p><b> Y </b></p><p><b> N</b></p><p&
41、gt;<b> Y </b></p><p><b> N</b></p><p><b> 圖2 子程序流程圖</b></p><p><b> 六、程序運(yùn)行結(jié)果</b></p><p><b> 七、課程設(shè)計(jì)小結(jié)</b>
42、</p><p> 這次課程設(shè)計(jì)是在毫無準(zhǔn)備的尷尬情況下進(jìn)行的,在此之前,雖然學(xué)習(xí)了許多有關(guān)計(jì)算機(jī)網(wǎng)路以及通信原理的知識(shí),但是都是基于理論教學(xué)的。至于將網(wǎng)絡(luò)協(xié)議應(yīng)用到編程過程中,這還是頭一次,因此在設(shè)計(jì)的過程中遇到許多難題。在閱讀設(shè)計(jì)要求時(shí),一個(gè)概念困擾很久,多線程編程在之前并沒有接觸過,但是通過網(wǎng)絡(luò)查詢資料后得以理解其含義和作用。在計(jì)算機(jī)中,一個(gè)應(yīng)用程序在運(yùn)行狀態(tài)可以看做一個(gè)進(jìn)程,但是這就像做一項(xiàng)及其重要的過
43、程是同一個(gè)道理,在實(shí)際生活中,為了實(shí)現(xiàn)高效率的工作模式,通常是多個(gè)人同時(shí)來完成一項(xiàng)工作,或者說是很多人做同一樣事情,結(jié)果是同樣的時(shí)間可以實(shí)現(xiàn)大批量的工作。在這個(gè)過程當(dāng)中,參與該事件的人都可以使用現(xiàn)有的資源,這就是多線程共享進(jìn)程資源的原理。但是,在計(jì)算機(jī)線程中有一種特殊的情況,有的線程不能使用某些系統(tǒng)資源,這就稱作鎖,就好比有的線程將屬于自己的系統(tǒng)資源上了一把鎖,不允許其他線程使用這些資源??傊?,計(jì)算機(jī)多線程編程就是為了實(shí)現(xiàn)計(jì)算機(jī)快速、高
44、效率地執(zhí)行程序。</p><p> 通過此次課程設(shè)計(jì),我加深了對(duì)ICMP協(xié)議的理解,鞏固了課堂知識(shí)。由于網(wǎng)絡(luò)協(xié)議比較抽象、難學(xué),自己學(xué)得也不夠深入,加上還要把所學(xué)知識(shí)運(yùn)用到實(shí)踐中來,所以一開始時(shí)感覺比較困難,而且在調(diào)試過程中難免要出現(xiàn)一些如變量沒有定義、缺少頭文件、大小寫錯(cuò)誤以及其它問題,通過查閱文獻(xiàn)資料、向同學(xué)請(qǐng)教以及認(rèn)真地思考與分析,逐一對(duì)錯(cuò)誤進(jìn)行了調(diào)試,才使得程序能正常運(yùn)行,大體上符合了設(shè)計(jì)的目的和要求。
45、</p><p> 在程序的調(diào)試過程中,出現(xiàn)問題是正常的,關(guān)鍵是如何去發(fā)現(xiàn)問題的根源,然后去解決它。為了能夠快速地確定錯(cuò)誤的原因,盡快的排除程序錯(cuò)誤,通常把程序錯(cuò)誤劃分為三種類型:語(yǔ)法錯(cuò)誤、運(yùn)行錯(cuò)誤和邏輯錯(cuò)誤。在設(shè)計(jì)過程中,我們可以先找出問題,看是屬于哪一類錯(cuò)誤,然后再將問題一一解決,這樣既解決了疑難問題又節(jié)省了不少時(shí)間。</p><p><b> 參考文獻(xiàn)</b>
46、;</p><p> [1] 吳功宜, 胡曉英, 張仁, 何云, 王寧編著. 計(jì)算機(jī)網(wǎng)絡(luò)課程設(shè)計(jì). 北京:機(jī)械工業(yè)出版社, 2010.8</p><p> [2] 吳功宜著. 計(jì)算機(jī)網(wǎng)絡(luò). 北京:清華大學(xué)出版社, 2004</p><p> [3] 陳堅(jiān), 陳偉. Visual C++網(wǎng)絡(luò)高級(jí)編程[M]. 北京: 人民郵電出版社,2001</p>
47、<p> [4] 郭國(guó)強(qiáng). 計(jì)算機(jī)網(wǎng)絡(luò)與Internet教程. 北京: 清華出版社,2006.11</p><p> [5] 楊豐瑞, 楊豐任. 實(shí)用教程最新計(jì)算機(jī)網(wǎng)絡(luò). 北京: 中國(guó)鐵道出版社,2001.7</p><p><b> 附錄 源代碼</b></p><p> #pragma pack(4)</p>
48、<p> #pragma comment (lib,"Ws2_32.lib")</p><p> #define WIN32_LEAN_AND_MEAN</p><p> #include <winsock2.h></p><p> #include <stdio.h></p><
49、p> #include <stdlib.h></p><p> #include <iostream.h></p><p> #include <stdio.h></p><p> #include <sys/timeb.h></p><p> #include <time
50、.h></p><p> //IP報(bào)頭的數(shù)據(jù)結(jié)構(gòu)</p><p> typedef struct iphdr{</p><p> unsigned int headlen:4; //IP頭長(zhǎng)度</p><p> unsigned int version:4; //I
51、P版本號(hào)</p><p> unsigned char tos; //服務(wù)類型</p><p> unsigned short totallen; //IP包總長(zhǎng)度</p><p> unsigned short id;; //ID號(hào)</p&g
52、t;<p> unsigned short flag; //標(biāo)記</p><p> unsigned char ttl; //生存時(shí)間</p><p> unsigned char prot; //協(xié)議(UDP TCP)</p><
53、p> unsigned short checksum; //校驗(yàn)和</p><p> unsigned int sourceIP; //源IP</p><p> unsigned int destIP; //目的IP</p><p> }IpHeade
54、r;</p><p> //ICMP頭部的數(shù)據(jù)結(jié)構(gòu)</p><p> typedef struct icmphdr{</p><p> BYTE type; //ICMP類型碼,回送請(qǐng)求的類型碼為8</p><p> BYTE code; //子類型碼,保存與特定ICMP報(bào)文類型相關(guān)
55、細(xì)節(jié)信息</p><p> USHORT checksum; //校驗(yàn)和</p><p> USHORT id; //ICMP報(bào)文ID號(hào)(一般用進(jìn)程號(hào)作ID)</p><p> USHORT seg; //ICMP數(shù)據(jù)報(bào)的序列號(hào)</p><p&g
56、t; }IcmpHeader;</p><p> #define ICMP_RCHO 8 //請(qǐng)求回送</p><p> #define DEF_PACKET_SIZE 32 //缺省數(shù)據(jù)報(bào)長(zhǎng)度</p><p> #define MAX_PACKET 1024 //最大數(shù)據(jù)塊長(zhǎng)度
57、</p><p> #define ICMP_MIN 8 //ICMP報(bào)文頭長(zhǎng)度(最小ICMP報(bào)文長(zhǎng)度)</p><p> #define ICMP_RCHO_REPLY 0</p><p> #define STATUS_FAILED 0xFFFF</p><p> #define MAX_PING_PACKET_
58、SIZE (MAX_PACKET+sizeof(IpHeader))</p><p> void fill_icmp_data(char *,int);</p><p> USHORT checksum(USHORT *,int);</p><p> void decode_resp(char *,int,struct sockaddr_in *);</
59、p><p> DWORD WINAPI FindIP(LPVOID pIPAddrTemp);</p><p> WSADATA wsaData;</p><p> SOCKET sockRaw;//為了實(shí)現(xiàn)發(fā)送/監(jiān)聽I(yíng)CMP報(bào)文,必須使用原始套接字,創(chuàng)建原始套接字</p><p> struct sockaddr_in dest,fro
60、m,end;</p><p> int fromlen =sizeof(from);//from是一個(gè)sockaddr_in數(shù)據(jù)結(jié)構(gòu),用于保存響應(yīng)的目的的主機(jī)的地址</p><p> char *recvbuf=new char[MAX_PING_PACKET_SIZE];//保證大與發(fā)送包的大小</p><p> unsigned int addr=0;&l
61、t;/p><p> long ThreadNumCounter=0,ThreadNumLimit=20;</p><p> long *aa=&ThreadNumCounter;</p><p> void main(int argc,char *argv[])</p><p><b> {</b></
62、p><p> if(WSAStartup(MAKEWORD(2,1),&wsaData)!=0)</p><p><b> {</b></p><p> cout<<"WASStartup failed"<<GetLastError()<<endl;</p><
63、;p> ExitProcess(STATUS_FAILED);</p><p><b> }</b></p><p> sockRaw=WSASocket(AF_INET,SOCK_RAW,IPPROTO_ICMP,NULL,0,WSA_FLAG_OVERLAPPED);</p><p> if(sockRaw==INVALID_
64、SOCKET)</p><p><b> {</b></p><p> cout<<"WASSocketet() falied"<<WSAGetLastError()<<endl;</p><p> ExitProcess(STATUS_FAILED);</p><
65、;p><b> }</b></p><p> int timeout=1000;</p><p> int bread=setsockopt(sockRaw,SOL_SOCKET,SO_RCVTIMEO,(char *)&timeout,sizeof(timeout));</p><p> if(bread==SOCKET
66、_ERROR)</p><p><b> {</b></p><p> cout<<"FAILED TO SEY RECV TIMEOUT"<<WSAGetLastError()<<endl;</p><p> ExitProcess(STATUS_FAILED);</p>
67、;<p><b> }</b></p><p> timeout=1000;</p><p> bread=setsockopt(sockRaw,SOL_SOCKET,SO_SNDTIMEO,(char *)&timeout,sizeof(timeout));</p><p> if(bread==SOCKET_E
68、RROR)</p><p><b> {</b></p><p> cout<<"FAILED TO SEY RECV TIMEOUT"<<WSAGetLastError()<<endl;</p><p> ExitProcess(STATUS_FAILED);</p>
69、<p><b> }</b></p><p> memset(&dest,0,sizeof(dest));</p><p> unsigned long startIP,endIP;</p><p> dest.sin_family=AF_INET;</p><p> dest.sin_ad
70、dr.s_addr=inet_addr(argv[1]);</p><p> startIP=inet_addr(argv[1]);</p><p> end.sin_family=AF_INET;</p><p> end.sin_addr.s_addr=inet_addr(argv[2]);</p><p> endIP=inet
71、_addr(argv[2]);</p><p> HANDLE hThread;</p><p> while(htonl(startIP)<=htonl(endIP))</p><p><b> {</b></p><p> if(ThreadNumCounter>ThreadNumLimit)&l
72、t;/p><p><b> {</b></p><p> Sleep(5000);</p><p><b> continue;</b></p><p><b> }</b></p><p> DWORD ThreadID;</p>
73、<p> sockaddr_in *pIPAddrTemp=new (sockaddr_in);</p><p> if(!pIPAddrTemp)</p><p><b> {</b></p><p> cout<<"memory alloc failed"<<endl;</
74、p><p><b> return ;</b></p><p><b> }</b></p><p> *pIPAddrTemp=dest;</p><p> clock_t start;</p><p> start=clock();</p><p
75、> hThread=CreateThread(NULL,NULL,FindIP,(LPVOID)pIPAddrTemp,NULL,&ThreadID);</p><p> long i=60000000L;</p><p> while(i--);</p><p> TerminateThread(hThread,0);</p>
76、<p> InterlockedDecrement(aa);</p><p> memset(&from,0,sizeof(from));</p><p> startIP=htonl(htonl(startIP)+1);</p><p> dest.sin_addr.s_addr=startIP;</p><p>
77、<b> }</b></p><p> while(ThreadNumCounter!=0)</p><p><b> {</b></p><p> Sleep(2000);</p><p><b> return;</b></p><p>
78、 cout<<"error"<<endl;</p><p><b> }</b></p><p><b> }</b></p><p> void fill_icmp_data(char *icmp_data,int datasize)//ICMP報(bào)文的填充</p&g
79、t;<p><b> {</b></p><p> IcmpHeader *icmp_hdr;</p><p> char *datapart;</p><p> icmp_hdr = (IcmpHeader*)icmp_data;</p><p> icmp_hdr->type = ICM
80、P_RCHO; //設(shè)置類型</p><p> icmp_hdr->id = (USHORT)GetCurrentThreadId(); //設(shè)置其ID號(hào)為當(dāng)前線程號(hào)</p><p> datapart = icmp_data + sizeof(IcmpHeader); //計(jì)算出數(shù)據(jù)報(bào)的數(shù)據(jù)部分</p><p>
81、; memset(datapart,'A',datasize-sizeof(IcmpHeader)); //填入數(shù)據(jù)</p><p><b> }</b></p><p> void decode_resp(char *buf,int bytes,struct sockaddr_in *from)</p><p><
82、;b> {</b></p><p> IpHeader *iphdr;</p><p> IcmpHeader *icmphdr;</p><p> unsigned short iphdrlen;</p><p> iphdr=(IpHeader*) buf;</p><p> iphd
83、rlen = iphdr->headlen*4 ; //IP報(bào)頭的長(zhǎng)度</p><p> icmphdr=(IcmpHeader *)(buf+iphdrlen); //跳過IP報(bào)頭 </p><p> if(bytes<iphdrlen+ICMP_MIN) return; //數(shù)據(jù)包太短,丟棄 </p><p> if
84、(icmphdr->type !=ICMP_RCHO_REPLY) return;//不是回送響應(yīng)(Ping應(yīng)答),丟棄 </p><p> if(icmphdr->id!=(USHORT)GetCurrentThreadId()) return; //Id號(hào)不相符,丟棄 </p><p> cout<<"活動(dòng)主機(jī):"<<
85、inet_ntoa(from->sin_addr)<<endl;//輸出正在使用的IP地址</p><p> cout<<" "<<inet_ntoa(from->sin_addr)<<endl;</p><p><b> }</b></p><p>
86、; USHORT checksum(USHORT *buffer,int size) // //計(jì)算校驗(yàn)和</p><p><b> {</b></p><p> unsigned long cksum=0;</p><p> while(size>1)</p><p><b> {</b
87、></p><p> cksum+=*buffer++;</p><p> size-=sizeof(USHORT);</p><p><b> }</b></p><p><b> if(size)</b></p><p><b> {</b
88、></p><p> cksum+=*(UCHAR*)buffer;</p><p><b> }</b></p><p> cksum=(cksum>>16)+(cksum& 0xffff);</p><p> cksum+=(cksum>>16);</p>
89、<p> return (USHORT)(~cksum);</p><p><b> }</b></p><p> DWORD WINAPI FindIP(LPVOID pIPAddrTemp)</p><p><b> {</b></p><p> InterlockedInc
90、rement(aa);</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> int datasize=DEF_PACKET_SIZE;//ICMP數(shù)據(jù)報(bào)報(bào)文體的缺省長(zhǎng)度</p&g
91、t;<p> datasize+=sizeof(IcmpHeader); //再加上ICMP頭部的長(zhǎng)度</p><p> fill_icmp_data(icmp_data,datasize);</p><p> ((IcmpHeader*)icmp_data)->seg= 0; //序列號(hào)為0</p><p>
92、 ((IcmpHeader*)icmp_data)->checksum = 0; //先將校驗(yàn)和置0</p><p> ((IcmpHeader*)icmp_data)->checksum=checksum((USHORT*)icmp_data,datasize);</p><p> int bwrote=sendto(sockRaw,icmp_data
93、,datasize,0,(struct sockaddr *)pIPAddrTemp,sizeof(dest));</p><p><b> int n=0;</b></p><p> if(bwrote==SOCKET_ERROR)</p><p><b> {</b></p><p>
94、if(WSAGetLastError()==WSAETIMEDOUT)</p><p><b> {</b></p><p> cout<<"timed out"<<endl;</p><p><b> }</b></p><p> cout<
95、;<"sendto failies"<<WSAGetLastError()<<endl;</p><p> ExitProcess(STATUS_FAILED);</p><p><b> n=1;</b></p><p><b> }</b></p>
96、<p> if(WSAGetLastError()==WSAETIMEDOUT)</p><p><b> {</b></p><p> cout<<"timed out"<<endl;</p><p> ExitProcess(STATUS_FAILED);</p>
97、<p><b> n=1;</b></p><p><b> }</b></p><p> if(bwrote<datasize)</p><p><b> {</b></p><p> cout<<"Worte"<
98、;<bwrote<<"bytes"<<endl;</p><p> ExitProcess(STATUS_FAILED);</p><p><b> n=1;</b></p><p><b> }</b></p><p> int bread
99、=recvfrom(sockRaw,recvbuf,MAX_PING_PACKET_SIZE,0,(struct sockaddr *)&from,&fromlen);</p><p> if(bread==SOCKET_ERROR)</p><p><b> {</b></p><p> if(WSAGetLastErr
100、or()==WSAETIMEDOUT)</p><p><b> {</b></p><p> cout<<"timed out"<<endl;</p><p><b> }</b></p><p> cout<<"recvf
101、rom falied"<<WSAGetLastError()<<endl;</p><p> ExitProcess(STATUS_FAILED);</p><p><b> n=1;</b></p><p><b> }</b></p><p><b&
102、gt; if(n==0)</b></p><p><b> {</b></p><p> decode_resp(recvbuf,bread,&from);</p><p> InterlockedDecrement(aa);</p><p><b> }</b><
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 眾賞文庫(kù)僅提供信息存儲(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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 發(fā)現(xiàn)網(wǎng)絡(luò)中的活動(dòng)主機(jī)--計(jì)算機(jī)網(wǎng)絡(luò)課程設(shè)計(jì)
- 基于活動(dòng)的網(wǎng)絡(luò)課程設(shè)計(jì).pdf
- 學(xué)校網(wǎng)絡(luò)設(shè)計(jì)課程設(shè)計(jì)報(bào)告
- 網(wǎng)絡(luò)工程實(shí)踐課程設(shè)計(jì)報(bào)告--校園網(wǎng)網(wǎng)絡(luò)課程設(shè)計(jì)
- 網(wǎng)絡(luò)營(yíng)銷課程設(shè)計(jì)報(bào)告
- web課程設(shè)計(jì) 《web網(wǎng)絡(luò)編程技術(shù)》課程設(shè)計(jì)報(bào)告
- 課程設(shè)計(jì)報(bào)告-- 小區(qū)網(wǎng)絡(luò)光纖的鋪設(shè)
- 網(wǎng)絡(luò)攻擊與防御課程設(shè)計(jì)報(bào)告
- des課程設(shè)計(jì)報(bào)告--網(wǎng)絡(luò)安全
- java課程設(shè)計(jì)----課程設(shè)計(jì)報(bào)告
- fpga課程設(shè)計(jì)課程設(shè)計(jì)報(bào)告
- 網(wǎng)絡(luò)課程設(shè)計(jì)報(bào)告---公司網(wǎng)絡(luò)組建設(shè)計(jì)與方案
- 基于角色典型活動(dòng)分析的網(wǎng)絡(luò)課程設(shè)計(jì)與開發(fā)
- uml課程設(shè)計(jì)報(bào)告-網(wǎng)絡(luò)教學(xué)系統(tǒng)
- 網(wǎng)絡(luò)協(xié)議分析與仿真課程設(shè)計(jì)報(bào)告
- 網(wǎng)絡(luò)安全課程設(shè)計(jì)--基于認(rèn)證的攻擊設(shè)計(jì)報(bào)告
- 大型企業(yè)網(wǎng)絡(luò)設(shè)計(jì)-網(wǎng)絡(luò)工程課程設(shè)計(jì)報(bào)告
- 網(wǎng)絡(luò)課程設(shè)計(jì)模板
- 網(wǎng)絡(luò)工程課程設(shè)計(jì)報(bào)告--網(wǎng)絡(luò)架構(gòu)結(jié)構(gòu)設(shè)計(jì)
- 網(wǎng)絡(luò)編程課程設(shè)計(jì)報(bào)告--基于linux網(wǎng)絡(luò)聊天室設(shè)計(jì)
評(píng)論
0/150
提交評(píng)論