Ping程序設(shè)計(jì)_第1頁
Ping程序設(shè)計(jì)_第2頁
Ping程序設(shè)計(jì)_第3頁
Ping程序設(shè)計(jì)_第4頁
Ping程序設(shè)計(jì)_第5頁
已閱讀5頁,還剩16頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

1、計(jì)算機(jī)科學(xué)與技術(shù)學(xué)院課程設(shè)計(jì)成績單課程名稱:計(jì)算機(jī)網(wǎng)絡(luò)課程設(shè)計(jì) 指導(dǎo)教師:李鵬 姓名丁勇性別男學(xué)號200922146159班級軟件091綜合成績成績等級程序運(yùn)行情況(占總成績20%)能正確運(yùn)行 基本能正確運(yùn)行 能運(yùn)行但結(jié)果不完善(20分) (15分) (10分)程序功能的完善程度(占總成績10%)完善 基本完善 不完善(10分) (8分) (5分)程序結(jié)構(gòu)的合理性(占總成績10%)合理 基本合理 不太合理(10分) (8分) (5分)對問題的答辯情況(占總成績40%)概念正確有創(chuàng)新 能正確回答所有問題 基本能正確回答(40分) (35分) (30分)部分問題回答概念不清晰(20分)學(xué)生的工作態(tài)

2、度與獨(dú)立工作能力(占總成績10%)工作態(tài)度認(rèn)真能獨(dú)立完成任務(wù) 工作態(tài)度認(rèn)真但獨(dú)立性較差(10分) (8分)工作態(tài)度基本認(rèn)真但缺乏獨(dú)立性(5分)設(shè)計(jì)報(bào)告的規(guī)范性(占總成績10%)符合規(guī)范 基本符合規(guī)范 規(guī)范性較差(10分) (8分) (5分)優(yōu)秀:90分100分 良好:80分89分 中等:7079分 及格:6069分 不及格0分59分 武漢科技大學(xué)計(jì)算機(jī)科學(xué)與技術(shù)學(xué)院制表 計(jì)算機(jī)科學(xué)與技術(shù)學(xué)院 課 程 設(shè) 計(jì) 報(bào) 告課程名稱: 計(jì)算機(jī)網(wǎng)絡(luò) 專 業(yè): 軟件工程 班 級: 09 級 01 班 學(xué) 號: 200922146159 姓 名: 丁勇 指導(dǎo)老師: 李鵬 基于Socket的PING程序設(shè)計(jì)pi

3、ng命令是使用頻率極高的一個(gè)網(wǎng)絡(luò)測試命令,用以測試從一個(gè)主機(jī)到另一個(gè)主機(jī)間的網(wǎng)絡(luò)上否可達(dá)。windows自帶的ping命令具有強(qiáng)大的功能,它有很多選項(xiàng)用于實(shí)現(xiàn)不同的測試目的。本章模仿windows的ping命令,用c語言實(shí)現(xiàn)了一個(gè)簡單的命令。本章著重講述ping命令的實(shí)現(xiàn)原理和c語言的網(wǎng)絡(luò)編程方法。讀者可以在本章的基礎(chǔ)上,對本章實(shí)現(xiàn)的ping命令進(jìn)行擴(kuò)展,開發(fā)出功能更強(qiáng)大、更完善的ping命令,并進(jìn)一步掌握網(wǎng)絡(luò)編程的方法。1、設(shè)計(jì)目的本章通過設(shè)計(jì)Ping程序,講解Ping程序的實(shí)現(xiàn)原理,并初步講解了c語言網(wǎng)絡(luò)編程技術(shù)。本章涉及很多網(wǎng)絡(luò)編程函數(shù)和編程技巧。包括庫文件的導(dǎo)入;winsock的初始化

4、、注銷;socket的創(chuàng)建、關(guān)閉;設(shè)置socket選項(xiàng);根據(jù)主機(jī)名獲取IP地址;從堆中分配一定數(shù)量的空間、釋放從堆中分配的空間;獲取當(dāng)前進(jìn)程ID號;數(shù)據(jù)報(bào)的發(fā)送;數(shù)據(jù)報(bào)的接等。通過本程序的訓(xùn)練,使讀者對網(wǎng)絡(luò)編程有一定的了解,掌握Ping程序的設(shè)計(jì)方法,掌握網(wǎng)絡(luò)編程的方法和技巧,從而編寫出功能更強(qiáng)大的程序。2、功能描述本章用 c語言實(shí)現(xiàn)的 ping命令,能用于測試一個(gè)主機(jī)到另一個(gè)主機(jī)間的聯(lián)通情況,程序還提供了幾個(gè)選項(xiàng)以實(shí)現(xiàn)不同的功能。(1)實(shí)現(xiàn)ping功能。程序能實(shí)現(xiàn)基本的ping操作,發(fā)送ICMP回顯請求報(bào)文,接收應(yīng)答報(bào)文。(2)能記錄路由。程序提供了“-r”選項(xiàng),用以記錄從源主機(jī)到目的主機(jī)的

5、路由。(3)能輸出指定條數(shù)的記錄。程序提供了“-n”選項(xiàng),用以輸出指定條數(shù)的記錄。(4)能按照指定大小輸出每條記錄。程序提供了“datasize”選項(xiàng),用以指定輸出的數(shù)據(jù)報(bào)的大小。(5)能輸出用戶幫助。程序提供了用戶幫助,顯示程序提供的選項(xiàng)以及選項(xiàng)格式等。3、總體設(shè)計(jì)3.1、功能模塊設(shè)計(jì)3.1.1、 功能模塊圖本系統(tǒng)共有 4 個(gè)模塊,分別是初始化模塊、功能控制模塊、數(shù)據(jù)控制模塊、數(shù)據(jù)報(bào)解讀模塊和ping測試模塊,如圖9.1所示。各模塊功能描述如下。Ping程序設(shè)計(jì)初始化模塊數(shù)據(jù)報(bào)解讀模塊功能控制模塊Ping測試模塊系統(tǒng)模塊圖(1) 初始化模塊。該模塊用于初始化各個(gè)全局變量,為全局變量賦初始值;

6、初始化,加載庫。(2)功能控制模塊。該模塊是被其它模塊調(diào)用,其功能包括獲取參數(shù)、計(jì)算校驗(yàn)和填充數(shù)據(jù)報(bào)文、釋放占用資源和顯示用戶幫助。(3)數(shù)據(jù)報(bào)解讀模塊。該模塊用于解讀接收到的報(bào)文和選項(xiàng)。(4)測試模塊。該模塊是本程序的核心模塊,調(diào)用其他模塊實(shí)現(xiàn)其功能,主要是實(shí)現(xiàn)的功能。 3.1.2、系統(tǒng)流程圖系統(tǒng)執(zhí)行的流程圖9.2所示。程序首先調(diào)用IniPing()函數(shù)初始化各全局變量,然后GetArgments()函數(shù)獲取用戶輸入的參數(shù),檢查用戶輸入的參數(shù),如果參數(shù)不正確或者沒有輸入?yún)?shù),則顯示用戶幫助信息(User help ),并結(jié)束程序;如果參數(shù)正確,則對指定目的地執(zhí)行Ping命令,如果Ping通,

7、則顯示Ping結(jié)果并釋放占用資源,如果沒有Ping通,則報(bào)告錯(cuò)誤信息,并釋放占用資源。開始初始化個(gè)變量獲取參數(shù)信息輸入?yún)?shù)是否正確?Ping目的地Ping成功?輸出Ping結(jié)果釋放占用資源結(jié)束輸出錯(cuò)誤信息顯示幫助信息圖9.2 系統(tǒng)流程圖3.1.3、參數(shù)獲取(GetArgments()函數(shù))流程圖獲取的參數(shù)包括“-r”(記錄路由)、“-n”(記錄條數(shù)程序,任意的整數(shù))和datasize(數(shù)據(jù)報(bào)大小)。程序首先判斷每一個(gè)參數(shù)的第一字符,如果第一個(gè)字符是“-”(短橫線),則認(rèn)為是“-r”或者“-n”中的一個(gè),然后作進(jìn)一步判斷。如果該參數(shù)的第二個(gè)字符是數(shù)字,則判斷該參數(shù)為記錄的條數(shù),如果該參數(shù)的第二個(gè)

8、字符是“r”,則判斷該參數(shù)為“-r”, 用于記錄路由;如果參數(shù)的第一個(gè)字符是數(shù)字,則認(rèn)為 參數(shù)是IP地址;或者datasize,然后作進(jìn)一步的判斷。如果該參數(shù)中不存在非數(shù)字的字符, 則判斷該參數(shù)為datasize;如果存在非數(shù) 字的字符,則判斷該參數(shù)為IP地址;其他情況則判斷為主機(jī)名。參數(shù)獲取的流程如圖9.3所示。開始Argc=1?檢查第i個(gè)參數(shù)的第一個(gè)字符是“-”?檢查第i個(gè)參數(shù)的第二個(gè)字符是數(shù)字?該參數(shù)表示要獲取的記錄數(shù)轉(zhuǎn)換成十進(jìn)制記錄到全局變量packetNUM還有參數(shù)?結(jié)束是數(shù)字?該參數(shù)中有非數(shù)字字符?該參數(shù)表示IP地址該參數(shù)表示數(shù)據(jù)報(bào)大小該參數(shù)表示主機(jī)名是“r”?顯示用戶幫助設(shè)標(biāo)志位

9、RecordFlag為turei=i+1記錄到變量Lpdest中記錄到變量Datasize中記錄到變量Lpdest中圖9.3 參數(shù)獲取流程圖3.1.4、ping()函數(shù)流程圖ping()函數(shù)是本程序的核心部分它調(diào)用其他模塊的函數(shù)來實(shí)現(xiàn),其主要步驟包括創(chuàng)建接字,設(shè)置路由選項(xiàng)(如果需要的話)、設(shè)置接收和發(fā)送超時(shí)值、名字解析(如果需要的話)、分配內(nèi)存、創(chuàng)建ICMP報(bào)文、發(fā)送ICMP請求報(bào)文、接收ICMP應(yīng)答報(bào)文和解讀ICMP報(bào)文。其執(zhí)行流程如圖9.4所示。 圖9.4 Ping 函數(shù)流程圖3. 2、數(shù)據(jù)結(jié)構(gòu)設(shè)計(jì) 本程序定義了3個(gè)結(jié)構(gòu)體:-iphdr、-icmphdr、和-ipotionhdr,分別用于

10、存放IP報(bào)頭信息、ICM P報(bào)頭信息和IP路由選項(xiàng)信息。3.2.1、定義IP報(bào)頭結(jié)構(gòu)體Typedef struct _iphdr Unsigned int h_len:4;Unsigned int version:4;Unsigned char tos;Unsigned short total_len;Unsigned short ident;Unsigned short frag_flags;Unsigned char ttl;Unsigned chor proto;Unsigned short checksum;Unsigned int sourceIP;Unsigned int dest

11、IP; IpHeader; 其中各字段表示意義如下。 h-len:4 : 表示IP報(bào)頭長度,首部長度指的是首部占32bit字的數(shù)目,包括任何選項(xiàng)。由于它是一個(gè)4bit 字段,因此首部最長為60個(gè)字節(jié),不包括任何選項(xiàng)的IP報(bào)頭是20個(gè)字節(jié)。 version:4: 表示IP的版本號,這里表示Ipv4.。 top: 表示服務(wù)的類型,可以表示最小時(shí)延,最大吞吐量,最高可靠性和最小費(fèi)用。 total len: 整個(gè)IP數(shù)據(jù)報(bào)的總長度。 ident: 唯一的標(biāo)識符,標(biāo)識主機(jī)發(fā)送的每一份數(shù)據(jù)報(bào)。 frag-flags: 分段標(biāo)志,表示過長的數(shù)據(jù)報(bào)是否要分段。 ttl: 生存期,表示數(shù)據(jù)報(bào)可以經(jīng)過的最多路由器

12、數(shù)。 proto: 協(xié)議類型(TCP、UDP等)。 checksum: 校驗(yàn)和。 sourceIP: 源IP地址。destIP: 目的IP地址。3.2.2、定義ICMP報(bào)頭結(jié)構(gòu)體Typedef struct icmphdr BYTE i_type; BYTE i_code : USHORT i_cksum; USHORT i_id; USHORT i_seq; ULONG timestamp; IcmpHeader; 其中各字段表示意義如下。 i_type : ICMP報(bào)文類型。i_code : 該類型中的代碼號,一種ICMP 報(bào)文的類型號和該類型中的代碼號共同決定。、 i_cksum: 校驗(yàn)

13、和。 i_seq: 序列號,序列號從0開始,每發(fā)送一次新的回顯請求就加1. timestamp: 時(shí)間戳。3.2.3、定義IP 選項(xiàng)結(jié)構(gòu)體Typedef struct _ipoptionhdr Unsigned char code; Unsigned char len; Unsigned char ptr; Unsigned loang addr9; IpOptionHeader;其中各字段表示意義如下。Code: 指明IP 選項(xiàng)類型,對于路由記錄選項(xiàng),它的值是7。Len: 選項(xiàng)頭長度。Ptr: 地址指針字段,是一個(gè)基于1的指針,指向存放下一個(gè)IP地址的位置。addr9: 記錄的Ip地址列表,

14、由于IP首部中選項(xiàng)的空間有限,所以可以記錄的Ip地址最多是9個(gè)。3.3、函數(shù)功能描述1) InitPing()函數(shù)原型:void IntPing()InitPing()函數(shù)用于初始化ping 所需的全局變量,為各個(gè)變量賦初始值。2)userHelp()函數(shù)原型:void userHelp() userHelp()函數(shù)用于顯示用戶幫助信息。當(dāng)程序檢查到參數(shù)錯(cuò)誤或者沒有必要的參數(shù)(如主機(jī)IP地址或者主機(jī)名)時(shí),則會調(diào)用此函數(shù)顯示幫助信息。3) GetArgments()函數(shù)原型:void GetArgments(int argc, char*argv)GetArgments()函數(shù)用于獲取用戶提交

15、的參數(shù)。其中argc 表示獲取的參數(shù)個(gè)數(shù),argv 用于存儲獲取的參數(shù),這兩個(gè)形參和主函數(shù)中的形參表示的意義一樣的。4)checkSum()函數(shù)原型:USHORT checkSum(USHORT *buffer,int size)checkSum()函數(shù)用于計(jì)算校驗(yàn)和。計(jì)算過程是首先把數(shù)據(jù)報(bào)頭中的校驗(yàn)和字段設(shè)置為0,然后對首部中每個(gè)16bit 進(jìn)行二字段進(jìn)制反碼求和(整個(gè)首部看成是由一串16bit的字組成),結(jié)果存在校驗(yàn)和字段中。 其中buffer 用于存放ICMP數(shù)據(jù),size表示ICMP報(bào)文大小。5)FillCMPData()函數(shù)原型:void FillCMPData()FillCMPDa

16、ta()函數(shù)用于填充ICMP數(shù)據(jù)報(bào)中各個(gè)字段。其中icmp_data 表示ICMP數(shù)據(jù),datasize 表示ICMP報(bào)文大小。6) FreeRes()函數(shù)原型:void FreeRes()FreeRes()函數(shù)用于釋放占用的資源,包括關(guān)閉初始化socket 調(diào)用的函數(shù)的、關(guān)閉創(chuàng)建的socket和釋放分配的內(nèi)存等。7)DecodeIPOptions()函數(shù)原型:void DecodeIPOptions()DecodeIPOptions()函數(shù)用于解讀IP選項(xiàng),從中讀出從源主機(jī)到目的主機(jī)經(jīng)過的路由,并輸出路由信息。Buf表示存放接收到的ICMP報(bào)文的緩沖區(qū),bytes表示接收到的字節(jié)數(shù)。8)De

17、codeICMPHeader()函數(shù)原型:void DecodeICMPHeader(char*buf, int bytes, SOCKADDR_IN*from)DecodeICMPHeader()函數(shù)用于解讀ICMP報(bào)文信息。Buf表示存放接收到的ICMP報(bào)文的緩沖區(qū),bytes表示接收到的字節(jié)數(shù),from 表示發(fā)送ICMP回顯應(yīng)答的主機(jī)IP地址。9)PingTest() 函數(shù)原型:void PingTest(int timeout)PingTest()函數(shù)用于進(jìn)行Ping操作。其中timeout表示設(shè)定的發(fā)送超時(shí)值。3.4、程序?qū)崿F(xiàn)3.4.1、 源碼分析1. 程序預(yù)處理/*導(dǎo)入庫文件*/#

18、pragma comment( lib, "ws2_32.lib" )/*加載頭文件*/#include <winsock2.h>#include <ws2tcpip.h>#include <stdio.h>#include <stdlib.h>#include <math.h>/*定義常量*/*表示要記錄路由*/#define IP_RECORD_ROUTE 0x7/*默認(rèn)數(shù)據(jù)報(bào)大小*/#define DEF_PACKET_SIZE 32 /*最大的ICMP數(shù)據(jù)報(bào)大小*/#define MAX_PACKET 10

19、24 /*最大IP頭長度*/#define MAX_IP_HDR_SIZE 60 /*ICMP報(bào)文類型,回顯請求*/ #define ICMP_ECHO 8/*ICMP報(bào)文類型,回顯應(yīng)答*/ #define ICMP_ECHOREPLY 0/*最小的ICMP數(shù)據(jù)報(bào)大小*/#define ICMP_MIN 8/*自定義函數(shù)原型*/void InitPing();void UserHelp();void GetArgments(int argc, char* argv); USHORT CheckSum(USHORT *buffer, int size);void FillICMPData(cha

20、r *icmp_data, int datasize);void FreeRes();void DecodeIPOptions(char *buf, int bytes);void DecodeICMPHeader(char *buf, int bytes, SOCKADDR_IN* from);void PingTest(int timeout);/*IP報(bào)頭字段數(shù)據(jù)結(jié)構(gòu)*/typedef struct _iphdr unsigned int h_len:4; /*IP報(bào)頭長度*/ unsigned int version:4; /*IP的版本號*/ unsigned char tos; /

21、*服務(wù)的類型*/ unsigned short total_len; /*數(shù)據(jù)報(bào)總長度*/ unsigned short ident; /*惟一的標(biāo)識符*/ unsigned short frag_flags; /*分段標(biāo)志*/ unsigned char ttl; /*生存期*/ unsigned char proto; /*協(xié)議類型(TCP、UDP等)*/ unsigned short checksum; /*校驗(yàn)和*/ unsigned int sourceIP; /*源IP地址*/ unsigned int destIP; /*目的IP地址*/ IpHeader;/*ICMP報(bào)頭字段數(shù)

22、據(jù)結(jié)構(gòu)*/typedef struct _icmphdr BYTE i_type; /*ICMP報(bào)文類型*/ BYTE i_code; /*該類型中的代碼號*/ USHORT i_cksum; /*校驗(yàn)和*/ USHORT i_id; /*惟一的標(biāo)識符*/ USHORT i_seq; /*序列號*/ ULONG timestamp; /*時(shí)間戳*/ IcmpHeader;/*IP選項(xiàng)頭字段數(shù)據(jù)結(jié)構(gòu)*/typedef struct _ipoptionhdr unsigned char code; /*選項(xiàng)類型*/ unsigned char len; /*選項(xiàng)頭長度*/ unsigned cha

23、r ptr; /*地址偏移長度*/ unsigned long addr9; /*記錄的IP地址列表*/ IpOptionHeader;/*定義全局變量*/SOCKET m_socket;IpOptionHeader IpOption;SOCKADDR_IN DestAddr;SOCKADDR_IN SourceAddr;char *icmp_data;char *recvbuf;USHORT seq_no ;char *lpdest;int datasize;BOOL RecordFlag;double PacketNum;BOOL SucessFlag;2. 初始化模塊/*初始化變量函數(shù)*

24、/ void InitPing() WSADATA wsaData; icmp_data = NULL; seq_no = 0; recvbuf = NULL; RecordFlag = FALSE; lpdest = NULL; datasize = DEF_PACKET_SIZE; PacketNum = 5; SucessFlag = FALSE; /*Winsock初始化*/ if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) /*如果初始化不成功則報(bào)錯(cuò),GetLastError()返回發(fā)生的錯(cuò)誤信息*/ printf("WS

25、AStartup() failed: %dn", GetLastError(); return ; m_socket = INVALID_SOCKET;3. 功能控制模塊/*顯示信息函數(shù)*/void UserHelp() printf("UserHelp: ping -r <host> data sizen"); printf(" -r record routen"); printf(" -n record amountn"); printf(" host remote machine to pingn

26、"); printf(" datasize can be up to 1KBn"); ExitProcess(-1); /*獲取ping選項(xiàng)函數(shù)*/void GetArgments(int argc,char* argv) int i; int j; int exp; int len; int m; /*如果沒有指定目的地地址和任何選項(xiàng)*/ if(argc = 1) printf("nPlease specify the destination IP address and the ping option as follow!n"); User

27、Help(); for(i = 1; i < argc; i+) len = strlen(argvi); if (argvi0 = '-') /*選項(xiàng)指示要獲取記錄的條數(shù)*/ if(isdigit(argvi1) PacketNum = 0; for(j=len-1,exp=0;j>=1;j-,exp+) /*根據(jù)argvij中的ASCII值計(jì)算要獲取的記錄條數(shù)(十進(jìn)制數(shù))*/ PacketNum += (double)(argvij-48)*pow(10,exp); else switch (tolower(argvi1) /*選項(xiàng)指示要獲取路由信息*/ cas

28、e 'r': RecordFlag = TRUE; break; /*沒有按要求提供選項(xiàng)*/ default: UserHelp(); break; /*參數(shù)是數(shù)據(jù)報(bào)大小或者IP地址*/ else if (isdigit(argvi0) for(m=1;m<len;m+) if(!(isdigit(argvim) /*是IP地址*/ lpdest = argvi; break; /*是數(shù)據(jù)報(bào)大小*/ else if(m=len-1) datasize = atoi(argvi); /*參數(shù)是主機(jī)名*/ else lpdest = argvi; /*求校驗(yàn)和函數(shù)*/USHO

29、RT CheckSum(USHORT *buffer, int size) unsigned long cksum=0; while (size > 1) cksum += *buffer+; size -= sizeof(USHORT); if (size) cksum += *(UCHAR*)buffer; /*對每個(gè)16bit進(jìn)行二進(jìn)制反碼求和*/ cksum = (cksum >> 16) + (cksum & 0xffff); cksum += (cksum >>16); return (USHORT)(cksum);/*填充ICMP數(shù)據(jù)報(bào)字段函

30、數(shù)*/void FillICMPData(char *icmp_data, int datasize) IcmpHeader *icmp_hdr = NULL; char *datapart = NULL; icmp_hdr = (IcmpHeader*)icmp_data; /*ICMP報(bào)文類型設(shè)置為回顯請求*/ icmp_hdr->i_type = ICMP_ECHO; icmp_hdr->i_code = 0; /*獲取當(dāng)前進(jìn)程IP作為標(biāo)識符*/ icmp_hdr->i_id = (USHORT)GetCurrentProcessId(); icmp_hdr->i

31、_cksum = 0; icmp_hdr->i_seq = 0; datapart = icmp_data + sizeof(IcmpHeader); /*以數(shù)字0填充剩余空間*/ memset(datapart,'0',datasize-sizeof(IcmpHeader);/*釋放資源函數(shù)*/void FreeRes() /*關(guān)閉創(chuàng)建的套接字*/ if (m_socket != INVALID_SOCKET) closesocket(m_socket); /*釋放分配的內(nèi)存*/ HeapFree(GetProcessHeap(), 0, recvbuf); HeapF

32、ree(GetProcessHeap(), 0, icmp_data); /*注銷WSAStartup()調(diào)用*/ WSACleanup(); return ;4. 數(shù)據(jù)報(bào)解讀模塊/*解讀IP選項(xiàng)頭函數(shù)*/void DecodeIPOptions(char *buf, int bytes) IpOptionHeader *ipopt = NULL; IN_ADDR inaddr; int i; HOSTENT *host = NULL; /*獲取路由信息的地址入口*/ ipopt = (IpOptionHeader *)(buf + 20); printf("RR: ");

33、 for(i = 0; i < (ipopt->ptr / 4) - 1; i+) inaddr.S_un.S_addr = ipopt->addri; if (i != 0) printf(" "); /*根據(jù)IP地址獲取主機(jī)名*/ host = gethostbyaddr(char *)&inaddr.S_un.S_addr,sizeof(inaddr.S_un.S_addr), AF_INET); /*如果獲取到了主機(jī)名,則輸出主機(jī)名*/ if (host) printf("(%-15s) %sn", inet_ntoa(

34、inaddr), host->h_name); /*否則輸出IP地址*/ else printf("(%-15s)n", inet_ntoa(inaddr); return;/*解讀ICMP報(bào)頭函數(shù)*/void DecodeICMPHeader(char *buf, int bytes, SOCKADDR_IN *from) IpHeader *iphdr = NULL; IcmpHeader *icmphdr = NULL; unsigned short iphdrlen; DWORD tick; static int icmpcount = 0; iphdr =

35、(IpHeader *)buf; /*計(jì)算IP報(bào)頭的長度*/ iphdrlen = iphdr->h_len * 4; tick = GetTickCount(); /*如果IP報(bào)頭的長度為最大長度(基本長度是20字節(jié)),則認(rèn)為有IP選項(xiàng),需要解讀IP選項(xiàng)*/ if (iphdrlen = MAX_IP_HDR_SIZE) && (!icmpcount) /*解讀IP選項(xiàng),即路由信息*/ DecodeIPOptions(buf, bytes); /*如果讀取的數(shù)據(jù)太小*/ if (bytes < iphdrlen + ICMP_MIN) printf("T

36、oo few bytes from %sn", inet_ntoa(from->sin_addr); icmphdr = (IcmpHeader*)(buf + iphdrlen); /*如果收到的不是回顯應(yīng)答報(bào)文則報(bào)錯(cuò)*/ if (icmphdr->i_type != ICMP_ECHOREPLY) printf("nonecho type %d recvdn", icmphdr->i_type); return; /*核實(shí)收到的ID號和發(fā)送的是否一致*/ if (icmphdr->i_id != (USHORT)GetCurrentPr

37、ocessId() printf("someone else's packet!n"); return ; SucessFlag = TRUE; /*輸出記錄信息*/ printf("%d bytes from %s:", bytes, inet_ntoa(from->sin_addr); printf(" icmp_seq = %d. ", icmphdr->i_seq); printf(" time: %d ms", tick - icmphdr->timestamp); printf

38、("n"); icmpcount+; return;5. Ping 測試模塊/*ping函數(shù)*/void PingTest(int timeout) int ret; int readNum; int fromlen; struct hostent *hp = NULL; /*創(chuàng)建原始套接字,該套接字用于ICMP協(xié)議*/ m_socket = WSASocket(AF_INET, SOCK_RAW, IPPROTO_ICMP, NULL, 0,WSA_FLAG_OVERLAPPED); /*如果套接字創(chuàng)建不成功*/ if (m_socket = INVALID_SOCKET

39、) printf("WSASocket() failed: %dn", WSAGetLastError(); return ; /*若要求記錄路由選項(xiàng)*/ if (RecordFlag) /*IP選項(xiàng)每個(gè)字段用0初始化*/ ZeroMemory(&IpOption, sizeof(IpOption); /*為每個(gè)ICMP包設(shè)置路由選項(xiàng)*/ IpOption.code = IP_RECORD_ROUTE; IpOption.ptr = 4; IpOption.len = 39; ret = setsockopt(m_socket, IPPROTO_IP, IP_OPT

40、IONS,(char *)&IpOption, sizeof(IpOption); if (ret = SOCKET_ERROR) printf("setsockopt(IP_OPTIONS) failed: %dn",WSAGetLastError(); /*設(shè)置接收的超時(shí)值*/ readNum = setsockopt(m_socket, SOL_SOCKET, SO_RCVTIMEO,(char*)&timeout, sizeof(timeout); if(readNum = SOCKET_ERROR) printf("setsockopt(

41、SO_RCVTIMEO) failed: %dn",WSAGetLastError(); return ; /*設(shè)置發(fā)送的超時(shí)值*/ timeout = 1000; readNum = setsockopt(m_socket, SOL_SOCKET, SO_SNDTIMEO,(char*)&timeout, sizeof(timeout); if (readNum = SOCKET_ERROR) printf("setsockopt(SO_SNDTIMEO) failed: %dn",WSAGetLastError(); return ; /*用0初始化目

42、的地地址*/ memset(&DestAddr, 0, sizeof(DestAddr); /*設(shè)置地址族,這里表示使用IP地址族*/ DestAddr.sin_family = AF_INET; if (DestAddr.sin_addr.s_addr = inet_addr(lpdest) = INADDR_NONE) /*名字解析,根據(jù)主機(jī)名獲取IP地址*/ if (hp = gethostbyname(lpdest) != NULL) /*將獲取到的IP值賦給目的地地址中的相應(yīng)字段*/ memcpy(&(DestAddr.sin_addr), hp->h_addr

43、, hp->h_length); /*將獲取到的地址族值賦給目的地地址中的相應(yīng)字段*/ DestAddr.sin_family = hp->h_addrtype; printf("DestAddr.sin_addr = %sn", inet_ntoa(DestAddr.sin_addr); /*獲取不成功*/ else printf("gethostbyname() failed: %dn",WSAGetLastError(); return ; /*數(shù)據(jù)報(bào)文大小需要包含ICMP報(bào)頭*/ datasize += sizeof(IcmpHead

44、er); /*根據(jù)默認(rèn)堆句柄,從堆中分配MAX_PACKET內(nèi)存塊,新分配內(nèi)存的內(nèi)容將被初始化為0*/ icmp_data =(char*) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,MAX_PACKET); recvbuf =(char*) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,MAX_PACKET); /*如果分配內(nèi)存不成功*/ if (!icmp_data) printf("HeapAlloc() failed: %dn", GetLastError(); return ; /* 創(chuàng)建ICMP報(bào)文*/ memset(icmp_data,0,MAX_PACKET); F

溫馨提示

  • 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. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論