Ping程序設計(c語言課程設計)_第1頁
Ping程序設計(c語言課程設計)_第2頁
Ping程序設計(c語言課程設計)_第3頁
Ping程序設計(c語言課程設計)_第4頁
Ping程序設計(c語言課程設計)_第5頁
已閱讀5頁,還剩17頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

ping程序設計ping的網(wǎng)絡上否可達。windowsping命令具有強大的功能,它有很多項選擇項用于實現(xiàn)不同的測試目的。本章仿照windowsping命令,用c語言實現(xiàn)了一個簡潔的命令。本章著重pingc語言的網(wǎng)絡編程方法。讀者可以在本章的根底上,對本章實pingping命令,并進一步把握網(wǎng)絡編程的方法。設計目的PingPing程序的實現(xiàn)原理,并初步講解了c語言網(wǎng)絡編程技術。winsocksocket的創(chuàng)立、關閉;設置socket選項;依據(jù)主機名獵取IP地址;從堆中安排確定數(shù)量的空間、釋放從堆中安排的空間;獵取當前進程ID號;數(shù)據(jù)報的發(fā)送;數(shù)據(jù)報的接等。通過本程序的訓練,使讀者對網(wǎng)絡編程有確定的了解,把握Ping程序的設計方法,把握網(wǎng)絡編程的方法和技巧,從而編寫出功能更強大的程序。功能描述本章用c 語言實現(xiàn)的ping命令,能用于測試一個主機到另一個主機間的聯(lián)通狀況,程序還供給了幾個選項以實現(xiàn)不同的功能。ping功能。程序能實現(xiàn)根本的pingICMP回顯懇求報文,接收顯應答報文。能記錄路由。程序供給了“-r”選項,用以記錄從源主機到目的主機的路由。能輸出指定條數(shù)的記錄。程序供給了“-n”選項,用以輸出指定條數(shù)的記錄。datasize”選項,用以指定輸出的數(shù)據(jù)報的大小。能輸出用戶幫助。程序供給了用戶幫助,顯示程序供給的選項以及選項格式等??傮w設計功能模塊設計功能模塊圖本系統(tǒng)共有4個模塊,分別是初始化模塊、功能把握模塊、數(shù)據(jù)把握模塊、數(shù)據(jù)報ping9.1所示。各模塊功能描述如下。PingPing程序設計初功數(shù)Ping始能據(jù)測化控報試模制解模塊模讀塊塊模塊9.1系統(tǒng)模塊圖(1)(2)功能把握模塊。改模塊是被其它模塊調用,其功能包括獵取參數(shù)、計算校驗和填充數(shù)據(jù)報文、釋放占用資源和顯示用戶幫助。數(shù)據(jù)報解讀模塊。改模塊用于解讀接收到的報文和選項。測試模塊。改模塊是本程序的核心模塊,調用其他模塊實現(xiàn)其功能,主要是實現(xiàn)的功能。2.系統(tǒng)流程圖系統(tǒng)執(zhí)行的流程圖9.2所示。程序首先調用IniPing函數(shù)初始化各全局變量,然后GetArgments函數(shù)獵取用戶輸入的參數(shù),檢查用戶輸入的參數(shù),假設參數(shù)不正確或者沒有輸入?yún)?shù),則顯示用戶幫助信息(Userhelp),并完畢程序;假設參數(shù)正確,則對指定目的Ping命令,假設Ping通,則顯示Ping結果并釋放占用資源,假設沒有Ping通,則報告錯誤信息,并釋放占用資源。開頭開頭初始化個變量獵取參數(shù)信息輸入?yún)?shù)是否正確?Ping目的地顯示幫助信息Ping成功?輸出錯誤信息Ping結果釋放占用資源完畢9.2系統(tǒng)流程圖參數(shù)獵取〔GetArgments函數(shù)〕流程圖-〔記錄路由-〔記錄條數(shù)程序,任意的整數(shù)〕和datasize數(shù)據(jù)報大小〔短橫線,則認為是“-r”或者“-n”中的一個,然后作進一步推斷。假設該參數(shù)的其次個字符是數(shù)字,則-用于開頭Argc==1i個參數(shù)的第一個字符檢查第一i個參數(shù)的其次個字符是數(shù)字?是數(shù)字?該參數(shù)中有開頭Argc==1i個參數(shù)的第一個字符檢查第一i個參數(shù)的其次個字符是數(shù)字?是數(shù)字?該參數(shù)中有該參數(shù)表示要獵取的記錄數(shù)顯示用戶幫助Record該參數(shù)表示該參數(shù)表示轉換成十進制記錄到全局變FlagtureIP地址數(shù)據(jù)報大小packetNUM記錄到變量記錄到變量Lpdest中Datasize中還有參數(shù)?I=i+1完畢9.3參數(shù)獵取流程圖ping函數(shù)流程圖ping字,設置路由選項〔假設需要的話、設置接收和發(fā)送超時值、名字解析〔假設需要的話、安排內存、創(chuàng)立ICMP報文、發(fā)送ICMP懇求報文、接收ICMPICMP報9.4所示。開頭創(chuàng)立原始套接字創(chuàng)立成功?記錄路由?ICMP設置路由選項設置接收和發(fā)送超時值設置成功?名字解析?依據(jù)主機名獵取各種參數(shù)獵取成功?設置目的地址各項字段ICMP報文大小安排內存安排成功ICMP報文ICMP懇求發(fā)送成功?超時發(fā)送?輸出失敗信息 輸出超時發(fā)送 接收ICMP應答接收成功?接收成功?超時接收?輸出失敗信息輸出超時接收記錄數(shù)到達指定值?圖9.4 Ping函數(shù)流程圖數(shù)據(jù)構造設計本程序定義了3個構造體:-iphdr、-icmphdr、和-ipotionhdr,分別用于存放IP報頭信息、ICMP報頭信息和IP路由選項信息。IP報頭構造體Typedefstruct_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 destIP;}IpHeader;其中各字段表示意義如下。h-len:4 IP32bit由于它是一個4bit60個字節(jié),不包括任何選項的IP20個字節(jié)。Version:4: IPIpv4.。Top: 表示效勞的類型,可以表示最小時延,最大吞吐量,最高牢靠性和最小費用。Total–len: IP數(shù)據(jù)報的總長度。Ident: 唯一的標識符,標識主機發(fā)送的每一份數(shù)據(jù)報。Frag-flags: 分段標志,表示過長的數(shù)據(jù)報是否要分段。Ttl: 生存期,表示數(shù)據(jù)報可以經(jīng)過的最多路由器數(shù)。Proto: 協(xié)議類型〔TCP、UDP等。Checksum: 校驗和。sourceIP: IP地址。destIP: IP地址。定義ICMP報頭構造體Typedefstruct–icmphdr{BYTE i_type;BYTE i_code:USHORT i_cksum;USHORT i_id;USHORT i_seq;ULONG timestamp;} IcmpHeader;其中各字段表示意義如下。I_tye ICMP報文類型。I_code: 該類型中的代碼號,一種ICMP報文的類型號和該類型中的代碼號共同打算I_cksum: 校驗和。I_seq: 序列號,序列號從0開頭,每發(fā)送一次的回顯懇求就加1.Timestamp: 時間。IP選項構造體Typedef struct _ipoptionhdr{Unsignedcharcode;Unsignedcharlen;Unsignedcharptr;Unsignedloangaddr[9];} IcmpHeader;其中各字段表示意義如下。Code: 指明IP選項類型,對于路由記錄選項,它的值是7。Len: 選項頭長度。Ptr: 地址指針字段,是一個基于1的指針,指向存放下一個IP地址的位置。addr[9]: 記錄的Ip地址列表,由于IP首部中選項的空間有限,所以可以記錄的Ip地址最多是9個。9.33 函數(shù)功能描述1〕IntPing函數(shù)原型:void IntPingIntPing函數(shù)用于初始化ping所需的全局變量,為各個變量賦初始值。2)userHelp函數(shù)原型:void userHelpuserHelp函數(shù)用于顯示用戶幫助信息。當程序檢查到參數(shù)錯誤或者沒有必要的參數(shù)〔如IP地址或者主機名〕時,則會調用此函數(shù)顯示幫助信息。3) GetArgments函數(shù)原型:void GetArgments(intargc,char**argv)GetArgments函數(shù)用于獵取用戶提交的參數(shù)。其中argc表示獵取的參數(shù)個數(shù),argv用于存儲獵取的參數(shù),這兩個形參和主函數(shù)中的形參表示的意義一樣的。4)checkSum函數(shù)原型:USHORT checkSum(USHORT *buffer,int size)checkSum函數(shù)用于計算校驗和。計算過程是首先把數(shù)據(jù)報頭中的校驗和字段設置為0,然后對首部中每個16bit 進展二字段進制反碼求和〔整個首部看成是由一串16bit的字組成,結果存在校驗和字段中。buffer用于存放ICMP數(shù)據(jù),sizeICMP報文大小。5)FillCMPData函數(shù)原型:void FillCMPDataFillCMPDataICMP數(shù)據(jù)報中各個字段。其中icmp_data表示ICMP數(shù)據(jù),datasizeICMP報文大小。6) reeRes函數(shù)原型:void reeResreeRes函數(shù)用于釋放占用的資源,包括關閉初始化socket調用的函數(shù)的、關閉創(chuàng)立的socket和釋放安排的內存等。7)DecodeIPOptions函數(shù)原型:void DecodeIPOptionsIP選項,從中讀出從源主機到目的主機經(jīng)過的路由,并輸出路由信息。BufICMP報文的緩沖區(qū),bytes表示接收到的字節(jié)數(shù)。8)DecodelICMPHeader函數(shù)原型:void DecodelICMPHeader(char*buf,intbytes,SOCKADDR_IN*from)DecodelICMPHeader函數(shù)用于解讀ICMP報文信息。Buf表示存放接收到的ICMP報文的緩沖區(qū),bytes表示接收到的字節(jié)數(shù),from表示發(fā)送ICMP回顯應答的 主機IP 地址。9)PingTest函數(shù)原型:void PingTest(inttimeout)PingTestPingtimeout表示設定的發(fā)送超時值。9.4 程序實現(xiàn)9.1.4源碼分析程序預處理/*導入庫文件*/#pragmacomment(lib,“ws2_32.lib“)/*加載頭文件*/#include<winsock2.h>#include<ws2tcpip.h>#include<stdio.h>#include<stdlib.h>#include<math.h>/*定義常量*//*表示要記錄路由*/#defineIP_RECORD_ROUTE0x7/*默認數(shù)據(jù)報大小*/#defineDEF_PACKET_SIZE32/*ICMP數(shù)據(jù)報大小*/#defineMAX_PACKET1024/*IP頭長度*/#defineMAX_IP_HDR_SIZE60/*ICMP報文類型,回顯懇求*/#defineICMP_ECHO8/*ICMP報文類型,回顯應答*/#defineICMP_ECHOREPLY0/*ICMP數(shù)據(jù)報大小*/#defineICMP_MIN 8/*自定義函數(shù)原型*/voidInitPing;voidUserHelp;voidGetArgments(intargc,char**argv);USHORTCheckSum(USHORT*buffer,intsize);voidFillICMPData(char*icmp_data,intdatasize);voidFreeRes;voidDecodeIPOptions(char*buf,intbytes);voidDecodeICMPHeader(char*buf,intbytes,SOCKADDR_IN*from);voidPingTest(inttimeout);/*IP報頭字段數(shù)據(jù)構造*/typedefstruct_iphdr{unsignedint h_len:4; /*IP報頭長度*/unsignedint version:4; /*IP的版本號*/unsignedchar tos; /*效勞的類型*/unsignedshorttotal_len; /*數(shù)據(jù)報總長度*/unsignedshortident; /*惟一的標識符*/unsignedshortfrag_flags; /*分段標志*/unsignedchar ttl; /*生存期*/unsignedchar proto; /*協(xié)議類型(TCP、UDP等)*/unsignedshortchecksum; /*校驗和*/unsignedint sourceIP; /*源IP地址*/unsignedint destIP; /*目的IP地址*/}IpHeader;/*ICMP報頭字段數(shù)據(jù)構造*/typedefstruct_icmphdr{BYTE i_type; /*ICMP報文類型*/BYTE i_code; /*該類型中的代碼號*/USHORTi_cksum; /*校驗和*/USHORTi_id; /*惟一的標識符*/USHORTi_seq; /*序列號*/ULONG timestamp; /*時間戳*/}IcmpHeader;/*IP選項頭字段數(shù)據(jù)構造*/typedefstruct_ipoptionhdr{unsignedcharcode;/*選項類型*/unsignedcharlen;/*選項頭長度*/unsignedcharptr;/*地址偏移長度*/unsignedlongaddr[9];/*IP地址列表*/}IpOptionHeader;/*定義全局變量*/SOCKETm_socket;IpOptionHeaderIpOption;SOCKADDR_INDestAddr;SOCKADDR_INSourceAddr;char*icmp_data;char*recvbuf;USHORTseq_no;char*lpdest;intdatasize;BOOLRecordFlag;doublePacketNum;BOOLSucessFlag;初始化模塊/*初始化變量函數(shù)*/voidInitPing{WSADATAwsaData;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){/*假設初始化不成功則報錯,GetLastError返回發(fā)生的錯誤信息*/printf(“WSAStartupfailed:%d\n“,GetLastError);return;}}功能把握模塊/*顯示信息函數(shù)*/voidUserHelp{printf(“UserHelp:ping-r<host>[datasize]\n“);printf(“-rrecordroute\n“);printf(“-nrecordamount\n“);printf(“hostremotemachinetoping\n“);printf(“datasizecanbeupto1KB\n“);ExitProcess(-1);}/*ping選項函數(shù)*/voidGetArgments(intargc,char**argv){inti;intj;intlen;intm;/*假設沒有指定目的地地址和任何選項*/if(argc==1){printf(“\nPlease specify the destination IPaddress and the ping option follow!\n“);UserHelp;}for(i=1;i<argc;i++){=strlen(argv[i]);if(argv[i][0]==”-”){/*選項指示要獵取記錄的條數(shù)*/if(isdigit(argv[i][1])){}else{

PacketNum=0;for(j=len-1,exp=0;j>=1;j--,exp++)/*argv[i][j]ASCII值計算要獵取的記錄條數(shù)(十進制數(shù))*/PacketNum((double)(argv[i][j]-48))*pow(10,exp);switch(tolower(argv[i][1])){/*選項指示要獵取路由信息*/case”r”:RecordFlag=TRUE;break;/*沒有按要求供給選項*/default:UserHelp;break;}}}/*參數(shù)是數(shù)據(jù)報大小或者IP地址*/elseif(isdigit(argv[i][0])){for(m=1;m<len;m++){if(!(isdigit(argv[i][m]))){/*IP地址*/lpdest=argv[i];break;}/*是數(shù)據(jù)報大小*/elseif(m==len-1)datasize=atoi(argv[i]);}}/*參數(shù)是主機名*/elselpdest=argv[i];}}/*求校驗和函數(shù)*/USHORTCheckSum(USHORT*buffer,intsize){unsignedlongcksum=0;while(size>1){cksum+=*buffer++;size-=sizeof(USHORT);}if(size){cksum+=*(UCHAR*)buffer;}/*16bit進展二進制反碼求和*/cksum=(cksum>>16)+(cksum&0xffff);cksum(cksum>>16);return(USHORT)(~cksum);}/*ICMP數(shù)據(jù)報字段函數(shù)*/voidFillICMPData(char*icmp_data,intdatasize){IcmpHeader*icmp_hdr=NULL;char *datapart=NULL;icmp_hdr=(IcmpHeader*)icmp_data;/*ICMP報文類型設置為回顯懇求*/icmp_hdr->i_type=ICMP_ECHO;icmp_hdr->i_code0;/*IP作為標識符*/icmp_hdr->i_id=(USHORT)GetCurrentProcessId;icmp_hdr->i_cksum=0;icmp_hdr->i_seq=0;datapart=icmp_data+sizeof(IcmpHeader);/*0填充剩余空間*/memset(datapart,”0”,datasize-sizeof(IcmpHeader));}/*釋放資源函數(shù)*/voidFreeRes{/*關閉創(chuàng)立的套接字*/if(m_socket!=INVALID_SOCKET)closesocket(m_socket);/*釋放安排的內存*/HeapFree(GetProcessHeap,0,recvbuf);HeapFree(GetProcessHeap,0,icmp_data);調用*/WSACleanup;return;}數(shù)據(jù)報解讀模塊/*IP選項頭函數(shù)*/voidDecodeIPOptions(char*buf,intbytes){IpOptionHeader*ipopt=NULL;IN_ADDRinaddr;inti;HOSTENT*host=NULL;/*獵取路由信息的地址入口*/ipopt=(IpOptionHeader*)(buf+20);printf(“RR: “);for(i=0;i<(ipopt->ptr/4)-1;i++){inaddr.S_un.S_addr=ipopt->addr[i];if(i!=0)printf(“ “);/*IP地址獵取主機名*/host = gethostbyaddr((char *)&inaddr.S_un.S_addr,sizeof(inaddr.S_un.S_addr),AF_INET);/*假設獵取到了主機名,則輸出主機名*/if(host)printf(“(%-15s)%s\n“,inet_ntoa(inaddr),host->h_name);/*IP地址*/elseprintf(“(%-15s)\n“,inet_ntoa(inaddr));}return;}/*ICMP報頭函數(shù)*/voidDecodeICMPHeader(char*buf,intbytes,SOCKADDR_IN*from){IpHeader*iphdr=NULL;IcmpHeader*icmphdr=NULL;unsignedshortiphdrlen;DWORDtick;staticinticmpcount=0;iphdr=(IpHeader*)buf;/*IP報頭的長度*/iphdrlen=iphdr->h_len*4;tickGetTickCount;/*IP報頭的長度為最大長度(20字節(jié))IP選項,需要解讀IP選項*/if((iphdrlen==MAX_IP_HDR_SIZE)&&(!icmpcount))/*IP選項,即路由信息*/DecodeIPOptions(buf,bytes);/*假設讀取的數(shù)據(jù)太小*/if(bytes<iphdrlen+ICMP_MIN){printf(“Toofewbytesfrom%s\n“,inet_ntoa(from->sin_addr));}icmphdr=(IcmpHeader*)(buf+iphdrlen);/*假設收到的不是回顯應答報文則報錯*/if(icmphdr->i_type!=ICMP_ECHOREPLY){printf(“nonechotype%drecvd\n“,icmphdr->i_type);return;}/*ID號和發(fā)送的是否全都*/if(icmphdr->i_id!=(USHORT)GetCurrentProcessId){printf(“someoneelse”spacket!\n“);return;}SucessFlag=TRUE;/*輸出記錄信息*/printf(“%dbytesfrom%s:“,bytes,inet_ntoa(from->sin_addr));printf(“icmp_seq=%d.“,icmphdr->i_seq);printf(“time:%dms“,tick-icmphdr->timestamp);printf(“\n“);icmpcount++;return;}Ping測試模塊/*ping函數(shù)*/voidPingTest(inttimeout){intret;intreadNum;intfromlen;structhostent*hp=NULL;/*創(chuàng)立原始套接字,該套接字用于ICMP協(xié)議*/m_socket = WSASocket(AF_INET, SOCK_RAW, 0,WSA_FLAG_OVERLAPPED);/*假設套接字創(chuàng)立不成功*/{

NULL,printf(“WSASocketfailed:%d\n“,WSAGetLastError);return;}/*假設要求記錄路由選項*/if(RecordFlag){/*IP0初始化*/ZeroMemory(&IpOption,sizeof(IpOption));/*為每個ICMP包設置路由選項*/IpOption.code=IP_RECORD_ROUTE;IpOption.ptr =4;IpOption.len =39;ret = setsockopt(m_socket, IPPROTO_IP, IP_OPTIONS,(char *)&IpOption,sizeof(IpOption));if(ret==SOCKET_ERROR){printf(“setsockopt(IP_OPTIONS)failed:%d\n“,WSAGetLastError);}}/*設置接收的超時值*/readNum=setsockopt(m_socket,SOL_SOCKET,SO_RCVTIMEO,(char*)&timeout,sizeof(timeout));if(readNum==SOCKET_ERROR){printf(“setsockopt(SO_RCVTIMEO)failed:%d\n“,WSAGetLastError);return;}/*設置發(fā)送的超時值*/timeout1000;readNum=setsockopt(m_socket,SOL_SOCKET,SO_SNDTIMEO,(char*)&timeout,sizeof(timeout));if(readNum==SOCKET_ERROR){printf(“setsockopt(SO_SNDTIMEO)failed:%d\n“,WSAGetLastError);return;}/*0初始化目的地地址*/memset(&DestAddr,0,sizeof(DestAddr));/*設置地址族,這里表示使用IP地址族*/DestAddr.sin_familyAF_INET;if((DestAddr.sin_addr.s_addr=inet_addr(lpdest))==INADDR_NONE){/*IP地址*/if((hp=gethostbyname(lpdest))!=NULL){/*IP值賦給目的地地址中的相應字段*/memcpy(&(DestAddr.sin_addr),hp->h_addr,hp->h_length);/*將獵取到的地址族值賦給目的地地址中的相應字段*/DestAddr.sin_familyhp->h_addrtype;printf(“DestAddr.sin_addr=%s\n“,inet_ntoa(DestAddr.sin_addr));}/*獵取不成功*/else{printf(“gethostbynamefailed:%d\n“,WSAGetLastError);return;}}/*ICMP報頭*/datasizesizeof(IcmpHeader);/*依據(jù)默認堆句柄,從堆中安排MAX_PACKET內存塊,安排內存的內容將被初始0*/icmp_data =(char*) HeapAlloc(GetProcessHeap,HEAP_ZERO_MEMORY,MAX_PACKET);recvbuf =(char*) HeapAlloc(GetProcessHeap,HEAP_ZERO_MEMORY,MAX_PACKET);/*假設安排內存不成功*/if(!icmp_data){printf(“HeapAllocfailed:%d\n“,GetLastError);return;}/*ICMP報文*/memset(icmp_data,0,MAX_PACKET);FillICMPData(icmp_data,datasize);while(1){stat

溫馨提示

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

評論

0/150

提交評論