




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、課 程 設(shè) 計(jì) 課程名稱題目名稱學(xué)生學(xué)院專業(yè)班級(jí)學(xué) 號(hào)學(xué)生姓名指導(dǎo)教師2015 年 12月 28日目錄一、課程設(shè)計(jì)目的與意義二、課程設(shè)計(jì)的要求三、設(shè)計(jì)說明3.1、設(shè)計(jì)思路3.2、設(shè)計(jì)方案3.3、運(yùn)行環(huán)境3.4、設(shè)計(jì)重點(diǎn)四、詳細(xì)設(shè)計(jì) 4.1、主程序流程圖 4.2、校驗(yàn)和函數(shù)、釋放資源函數(shù)流程圖 4.3、ICMP報(bào)首部函數(shù)流程圖五、程序的結(jié)果與分析六、課程設(shè)計(jì)心得體會(huì)附錄一:參考文獻(xiàn)附錄二:程序源代碼一、 課程設(shè)計(jì)的目的與意義利用ICMP數(shù)據(jù)包、C語言實(shí)現(xiàn)Ping命令程序,能實(shí)現(xiàn)基本的Ping操作,發(fā)送ICMP回顯請(qǐng)求報(bào)文,用于測(cè)試個(gè)主機(jī)到只一個(gè)主機(jī)之間的連通情況。通過本程序的訓(xùn)練,熟悉ICMP報(bào)
2、文結(jié)構(gòu),對(duì)ICMP有更深的理解,掌握Ping程序的設(shè)計(jì)方法,掌握網(wǎng)絡(luò)編程的方法和技巧,從而編寫出功能更強(qiáng)大的程序。二、課程設(shè)計(jì)的要求1.已知參數(shù):目的節(jié)點(diǎn)IP地址或主機(jī)名2.設(shè)計(jì)要求:通過原始套接字編程,實(shí)現(xiàn)Ping的基本功能2.1初始化Windows Sockets網(wǎng)絡(luò)環(huán)境;2.2解析命令行參數(shù),構(gòu)造目的端socket地址;2.3定義IP、ICMP報(bào)文;2.4接收ICMP差錯(cuò)報(bào)文并進(jìn)行解析。三、設(shè)計(jì)說明1設(shè)計(jì)思路由于Ping程序是面向用戶的應(yīng)用程序,該程序使用ICMP的封裝機(jī)制,通過IP協(xié)議來工作。為了實(shí)現(xiàn)直接對(duì)IP和ICMP包進(jìn)行操作,實(shí)驗(yàn)中使用RAW模式的socket編程。首先定義IP數(shù)
3、據(jù)報(bào)首部,在IP數(shù)據(jù)報(bào)的基礎(chǔ)上定義ICMP數(shù)據(jù)報(bào)首部,并初始化一些全局變量。接著自定義填充ICMP數(shù)據(jù)報(bào)字段函數(shù)FillICMPData()、校驗(yàn)和函數(shù)checksum()、解讀ICMP報(bào)首部函數(shù)DecodeICMPHeader()、釋放資源函Cleanup()。最后主函數(shù)通過調(diào)用這些函數(shù)來實(shí)現(xiàn)Ping命令功能。2. 設(shè)計(jì)方案IP頭與ICMP頭的設(shè)置分別參照RFC791及RFC792的標(biāo)準(zhǔn),包含所有必要信息。主程序設(shè)置main()函數(shù),主函數(shù)用庫函數(shù)實(shí)現(xiàn)套接字編程用于數(shù)據(jù)包發(fā)送及接收,其中,數(shù)據(jù)包發(fā)送調(diào)用sendto(),數(shù)據(jù)包接收調(diào)用recvfrom( ),由于發(fā)送數(shù)據(jù)包時(shí)可能會(huì)遇到阻塞或者
4、目標(biāo)主機(jī)不通,造成超時(shí),因此需要在發(fā)送數(shù)據(jù)包后調(diào)用一個(gè)函數(shù)判斷是否超時(shí),此處調(diào)用庫函數(shù)setsockopt()來實(shí)現(xiàn)超時(shí)判斷;其次,校驗(yàn)和函數(shù)采用移位方法進(jìn)行計(jì)算。3. 系統(tǒng)運(yùn)行環(huán)境:VC+ 6.0, Window 7操作系統(tǒng)平臺(tái)4. 設(shè)計(jì)中的重點(diǎn)首先遇到的問題就是套接字文件的問題。套接字所需要的文件有頭文件Winsocket2.h、庫文件WS2_32.LIB、動(dòng)態(tài)庫W32_32.DLL。創(chuàng)建套接字的時(shí)候參數(shù)的以及在創(chuàng)建套接字之前必須首先使用WSAStartup函數(shù)、在使用完套接字之后要釋放內(nèi)存資源,關(guān)閉套接字這些問題都是以前未接觸過的。所以在寫程序的時(shí)候需要查閱大量的資料,弄懂這些問題。其次
5、,在套接字問題解決之后,遇到的難題,也是比較重要的問題就是如何實(shí)現(xiàn)ICMP報(bào)文的發(fā)送和接受,以及怎樣判斷發(fā)送、接收超時(shí)或者找不到目的主機(jī)。最后在程序調(diào)試的時(shí)候總是出現(xiàn)這樣或那樣的錯(cuò)誤,比如頭文件錯(cuò)誤、動(dòng)態(tài)庫無法導(dǎo)入、編輯器環(huán)境不匹配等。四、詳細(xì)設(shè)計(jì) 1、本程序主要是通過main()函數(shù)調(diào)用自定義函數(shù)以及其本身的一些功能,例如:打開socket動(dòng)態(tài)庫、設(shè)置接收和發(fā)送超時(shí)值、域名地址解析、分配內(nèi)存、創(chuàng)建及初始化ICMP報(bào)文、發(fā)送ICMP請(qǐng)求報(bào)文、接收ICMP 應(yīng)答報(bào)文以及解讀應(yīng)答報(bào)文和輸出Ping結(jié)果。程序流程圖如下:開始 定義及初始化各個(gè)全局變量判斷WSAStartup函數(shù)是否調(diào)用成功 否 輸出
6、調(diào)用失敗 是創(chuàng)建套接字以及設(shè)置socket接收超時(shí),發(fā)送超時(shí)選項(xiàng)輸入PING的IP地址解析輸入內(nèi)容,設(shè)置PING參數(shù)創(chuàng)建及填充ICMP數(shù)據(jù)報(bào)文判斷輸入的ip地址沒有-t并且已發(fā)四次 是Break 否 清除殘余 否發(fā)送,接收以及解析數(shù)據(jù)包結(jié)束輸出PIING結(jié)果2、校驗(yàn)和函數(shù)、釋放資源函數(shù)流程圖如下:cleanup開始Checksu開始 if (m_hSocket != INVALID_SOCKE定義初始化cksum(size > 1) 是關(guān)閉套接字 否 是 否定cksum及size大小釋放占用資源清除ICMP包數(shù)據(jù)以及接受緩沖區(qū)if (size)WSACleanup(); 是cksum+=
7、*(UCHAR*)buffer; 否 結(jié)束計(jì)算校驗(yàn)cksum,獲得結(jié)果結(jié)束3、ICMP報(bào)首部函數(shù)流程圖如下:DecodeICMPHeader定義相關(guān)變量以及初始化tick = GetTickCount()我們所要的回應(yīng)報(bào)文輸出不是我們所要tick0icmpcount=tick -icmphdr->timestamp結(jié)束判斷時(shí)間是否小于1msprintf("Reply from %s: dytes=%d time=%d icmp_seq = %dn",inet_ntoa(from->sin_addr)printf("Reply from %s: dyte
8、s=%d time<1ms icmp_seq = %dn",inet_ntoa(from->sin_addr)icmpcount+結(jié)束五、程序的結(jié)構(gòu)與分析 運(yùn)行結(jié)果截圖如下:結(jié)果分析:1、Request timed out(請(qǐng)求超時(shí))(1) 對(duì)方已關(guān)機(jī),或者網(wǎng)絡(luò)上根本沒有這個(gè)地址:比如在上圖中Ping 14.150.213.222(2)對(duì)方與自己不在同一網(wǎng)段內(nèi),通過路由也無法找到對(duì)方,但有時(shí)對(duì)方確實(shí)是存在的,當(dāng)然不存在也是返回超時(shí)的信息。(3)對(duì)方確實(shí)存在,但設(shè)置了ICMP數(shù)據(jù)包過濾(比如防火墻設(shè)置)。2、Destination host Unreachable(目標(biāo)不可
9、達(dá))(1)錯(cuò)誤設(shè)置IP地址六、課程設(shè)計(jì)心得體會(huì)本次課程設(shè)計(jì)較好地實(shí)現(xiàn)了要求做到的功能,但同時(shí)也遇到不少的困難和挑戰(zhàn)。通過這次設(shè)計(jì),不但加深了對(duì)Socket的原始套接字編程的理解,經(jīng)過實(shí)現(xiàn)Ping程序,熟悉了IP、ICMP等,掌握TCP/IP網(wǎng)絡(luò)協(xié)議的基本實(shí)現(xiàn)方法。也熟悉了Window網(wǎng)絡(luò)編程的技術(shù)。能熟悉地使用套接字進(jìn)行網(wǎng)絡(luò)通信。熟悉了數(shù)據(jù)通信的網(wǎng)絡(luò)技術(shù),同時(shí)學(xué)會(huì)了跟同學(xué)合作交流完成項(xiàng)目的討論方法和解決問題的能力。學(xué)會(huì)如果通過討論、交流、找資料來獨(dú)立解決所遇到的問題和不懂。更多地鍛煉了獨(dú)立解決問題的能力。在編寫過程中,一些基本的常見的函數(shù)不會(huì)應(yīng)用,這使我們小組都發(fā)現(xiàn)自己知識(shí)的匱乏,在以后的學(xué)習(xí)
10、過程中得要好好的努力,多閱讀一些復(fù)雜的程序,了解一個(gè)基本的函數(shù),算法和精良的編程思想,更要多動(dòng)手寫一些有一定難度的程序,我們不應(yīng)該害怕寫程序出錯(cuò),應(yīng)該大膽地寫出自己的想法,出現(xiàn)錯(cuò)誤去解決錯(cuò)誤就能找出自己知識(shí)的漏洞和模糊點(diǎn)。我們還可以通過閱讀別人錯(cuò)誤的程序,試著幫別人查找錯(cuò)誤,這樣證書技能頭腦中的規(guī)則還能發(fā)現(xiàn)一些初學(xué)者一番的錯(cuò)誤,使自己少走彎路。附錄一:參考文獻(xiàn)【1】 計(jì)算機(jī)網(wǎng)絡(luò) 謝希仁編著 電子工業(yè)出版社【2】C程序設(shè)計(jì) 譚浩強(qiáng)編著 北京清華大學(xué)出版社附錄二:程序源代碼及部分注釋#include "stdafx.h"#pragma comment(lib,"ws2
11、_32.lib")#include <winsock2.h>/創(chuàng)建套接字頭文件#include <ws2tcpip.h>#include <stdio.h>/標(biāo)準(zhǔn)輸入輸出函數(shù)#include <stdlib.h>/實(shí)用程序庫函數(shù)#include <string.h>#include <windows.h>typedef struct iphdr unsigned int h_len:4; / 頭長(zhǎng)度unsigned int version:4; / IP版本 unsigned char service; / 服務(wù)
12、類型 unsigned short total_len; / 包的總長(zhǎng)度 unsigned short ident; / 包標(biāo)示身份 unsigned short frag_and_flags; / 標(biāo)志 unsigned char ttl; / 包生命周期 unsigned char proto; / 協(xié)議類型 unsigned short checksum; / IP 校驗(yàn) unsigned int sourceIP; /源IP unsigned int destIP; /目標(biāo)IP IpHeader;#define ICMP_ECHO 8 /ICMP報(bào)文類型,回顯請(qǐng)求 #define IC
13、MP_ECHOREPLY 0 /ICMP報(bào)文類型,回顯響應(yīng)應(yīng)答#define ICMP_MIN 8 /最小的ICMP數(shù)據(jù)報(bào)大小 typedef struct icmphdr BYTE i_type; /ICMP報(bào)文類型 BYTE i_code; /該類型中的代碼號(hào) USHORT i_cksum; /校驗(yàn)和 USHORT i_id; /惟一的標(biāo)識(shí)符 USHORT i_seq; /序列號(hào) ULONG timestamp; /時(shí)間戳 IcmpHeader;#define DEF_PACKET_SIZE 32 /默認(rèn)數(shù)據(jù)報(bào)大小#define MAX_PACKET 1024 / 最大的ICMP數(shù)據(jù)報(bào)大小
14、 #define MAX_IP_HDR_SIZE 60 / 最大IP頭長(zhǎng)度 /初始化全局變量 int datasize=DEF_PACKET_SIZE;char *icmp_data=NULL;char *recvbuf=NULL;SOCKET m_hSocket= INVALID_SOCKET;char *lpdest=NULL;/填充ICMP數(shù)據(jù)報(bào)字段函數(shù)void FillICMPData(char *icmp_data, int datasize) IcmpHeader *icmp_hdr = NULL; char *datapart = NULL; icmp_hdr = (IcmpHe
15、ader*)icmp_data; icmp_hdr->i_type = ICMP_ECHO; icmp_hdr->i_code = 0; icmp_hdr->i_id = (USHORT)GetCurrentProcessId();/GetCurrentProcessId()獲取當(dāng)前進(jìn)程的標(biāo)示符(PID) icmp_hdr->i_cksum = 0; icmp_hdr->i_seq = 0; datapart = icmp_data + sizeof(IcmpHeader);/校驗(yàn)和函數(shù)USHORT checksum(USHORT *buffer, int siz
16、e) unsigned long cksum=0; while (size > 1) cksum += *buffer+; size -= sizeof(USHORT); if (size) cksum += *(UCHAR*)buffer; cksum = (cksum >> 16) + (cksum & 0xffff); cksum += (cksum >>16); return (USHORT)(cksum);/解讀ICMP報(bào)首部函數(shù)void DecodeICMPHeader(char *buf, int bytes, SOCKADDR_IN *fr
17、om) IpHeader *iphdr = NULL; IcmpHeader *icmphdr = NULL; unsigned short iphdrlen; DWORD tick; static int icmpcount = 0; iphdr = (IpHeader *)buf;/從buf中獲取IP數(shù)據(jù)包頭指針 iphdrlen = iphdr->h_len * 4; tick = GetTickCount(); if (bytes < iphdrlen + ICMP_MIN) printf("Too few bytes from %s rn",inet_
18、ntoa(from->sin_addr); icmphdr = (IcmpHeader*)(buf + iphdrlen);/定位ICMP包頭起始位置 if (icmphdr->i_type != ICMP_ECHOREPLY) printf("nonecho type %d received rn", icmphdr->i_type); if (icmphdr->i_id != (USHORT)GetCurrentProcessId() printf("其他程序的回應(yīng)報(bào)文! t錯(cuò)誤代碼 %dn", WSAGetLastError
19、(); int tick0;tick0=tick - icmphdr->timestamp;if(tick0<1)printf("Reply from%s: bytes=%d time<1ms icmp_seq =%dn",inet_ntoa(from->sin_addr), bytes, icmphdr->i_seq );else printf("Reply from %s: bytes=%d time=%dms icmp_seq =%dn",inet_ntoa(from->sin_addr), bytes,tick
20、0, icmphdr->i_seq); /釋放資源函數(shù)void Cleanup() if (m_hSocket != INVALID_SOCKET) closesocket(m_hSocket); HeapFree(GetProcessHeap(), 0, recvbuf); HeapFree(GetProcessHeap(), 0, icmp_data); WSACleanup();/主函數(shù)void main()WSADATA wsaData;char a100;printf("ping ");gets(a);lpdest=a;SOCKADDR_IN m_addrD
21、est;/結(jié)構(gòu)體SOCKADDR_IN m_addrFrom;int timeout=1000;USHORT seq_no=0;if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)printf("Sorry, you cannot load socket dll!");m_hSocket = WSASocket (AF_INET, SOCK_RAW, IPPROTO_ICMP, NULL, 0,WSA_FLAG_OVERLAPPED);/創(chuàng)建原始套接字,該套接字用于ICMP協(xié)議 if (m_hSocket = INVALID_
22、SOCKET) /如果套接字創(chuàng)建不成功 printf("socket 創(chuàng)建失敗!"); int bread = setsockopt(m_hSocket, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout);/設(shè)置接收的超時(shí)值 if(bread = SOCKET_ERROR) printf("設(shè)置socket接收超時(shí)選項(xiàng)錯(cuò)誤!"); timeout = 1000; bread = setsockopt(m_hSocket, SOL_SOCKET, SO_SNDTIMEO, (char
23、*)&timeout, sizeof(timeout);/設(shè)置發(fā)送的超時(shí)值 if (bread = SOCKET_ERROR) printf("設(shè)置socket發(fā)送超時(shí)選項(xiàng)錯(cuò)誤!"); memset(&m_addrDest, 0, sizeof(m_addrDest);/ 用0初始化目的地地址 m_addrDest.sin_family = AF_INET;/設(shè)置地址族,這里表示使用IP地址族 if (m_addrDest.sin_addr.s_addr = inet_addr(lpdest) = INADDR_NONE)/地址轉(zhuǎn)化 struct hoste
24、nt *hp = NULL; if (hp = gethostbyname(lpdest) != NULL) /名字解析,根據(jù)主機(jī)名獲取IP地址 memcpy(&(m_addrDest.sin_addr), hp->h_addr, hp->h_length);/將獲取到的IP值賦給目的地地址中的相應(yīng)字段m_addrDest.sin_family = hp->h_addrtype; /將獲取到的地址族值賦給目的地地址中的相應(yīng)字段 else printf("不能找到名為 %s 的主機(jī)t錯(cuò)誤代碼 %dn",lpdest, WSAGetLastError(
25、);/獲取不成功exit(0); printf("Pinging %s with 64 bytes of data: nn", inet_ntoa(m_addrDest.sin_addr); /inet_ntoa()將網(wǎng)絡(luò)地址轉(zhuǎn)換成“.”點(diǎn)隔的字符串格式 datasize += sizeof(IcmpHeader); /數(shù)據(jù)報(bào)文大小需要包含ICMP報(bào)頭/根據(jù)默認(rèn)堆句柄,從堆中分配MAX_PACKET內(nèi)存塊,新分配內(nèi)存的內(nèi)容將被初始化為0 icmp_data=(char*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,MAX_PACK
26、ET); recvbuf =(char*) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,MAX_PACKET); if (!icmp_data) /如果分配內(nèi)存不成功 printf("堆分配錯(cuò)誤!"); memset(icmp_data,0,MAX_PACKET);/將已開辟內(nèi)存空間 icmp_data 的首 MAX_PACKET 個(gè)字節(jié)的值設(shè)為值 0。 FillICMPData(icmp_data,datasize);/創(chuàng)建ICMP報(bào)文, / 開始發(fā)送或接受ICMP包int n
27、Count=0; while(1) int bwrote; if(strstr(a,"-t")=NULL&&nCount+=4) /判斷a字符數(shù)組中是否包含-t參數(shù)并且已發(fā)ICMP包4次 break;/超過指定的記錄條數(shù)則退出 (IcmpHeader*)icmp_data)->i_cksum = 0;/計(jì)算校驗(yàn)和前要把校驗(yàn)和字段設(shè)置為0 (IcmpHeader*)icmp_data)->timestamp = GetTickCount();/獲取操作系統(tǒng)啟動(dòng)到現(xiàn)在所經(jīng)過的毫秒數(shù),設(shè)置時(shí)間戳 (IcmpHeader*)icmp_data)->i_seq = seq_no+;/設(shè)置序列號(hào) (IcmpHeader*)icmp_data)->i_cksum = checksum(USHORT*)icmp_data, datasize);/計(jì)算校
溫馨提示
- 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. 人人文庫網(wǎng)僅提供信息存儲(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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 建筑構(gòu)件及橋梁構(gòu)件項(xiàng)目可行性研究報(bào)告申請(qǐng)報(bào)告
- 2024-2030年中國檳榔制品行業(yè)市場(chǎng)深度分析及投資潛力預(yù)測(cè)報(bào)告
- 2025年中國恒流量采樣器行業(yè)市場(chǎng)發(fā)展前景及發(fā)展趨勢(shì)與投資戰(zhàn)略研究報(bào)告
- 中國軌道交通車身系統(tǒng)行業(yè)發(fā)展運(yùn)行現(xiàn)狀及投資策略研究報(bào)告
- 中國中藥保健品行業(yè)市場(chǎng)前景預(yù)測(cè)及投資戰(zhàn)略研究報(bào)告
- 2025-2030年中國電子門票防偽系統(tǒng)項(xiàng)目投資可行性研究分析報(bào)告
- 2025年中國質(zhì)量檢驗(yàn)檢測(cè)行業(yè)市場(chǎng)發(fā)展現(xiàn)狀及投資前景展望報(bào)告
- 2024年中國家用塑料制品市場(chǎng)競(jìng)爭(zhēng)格局調(diào)查報(bào)告
- 2025年循環(huán)流化床鍋爐項(xiàng)目深度研究分析報(bào)告
- 鈣羧酸指示劑行業(yè)深度研究分析報(bào)告(2024-2030版)
- 2025年山東省德州市樂陵市中考一模生物學(xué)試題(含答案)
- 2025遼寧沈陽水務(wù)集團(tuán)有限公司招聘32人筆試參考題庫附帶答案詳解
- DB63-T 2135-2023 鹽湖資源動(dòng)態(tài)監(jiān)測(cè)技術(shù)規(guī)程
- 建筑行業(yè)現(xiàn)狀與發(fā)展趨勢(shì)
- 院外數(shù)據(jù)共享管理制度
- 陵園財(cái)務(wù)管理制度
- 2024年電力交易員(中級(jí)工)職業(yè)鑒定理論考試題庫-上(單選題)
- 杭州市西湖區(qū)部分校教科版五年級(jí)下冊(cè)期末檢測(cè)科學(xué)試卷(原卷版)
- 醫(yī)院.急救、備用藥品管理和使用及領(lǐng)用、補(bǔ)充管理制度及流程
- 按揭貸款業(yè)務(wù)合作協(xié)議書范本
- 2022年11月全國翻譯專業(yè)資格(水平)英語二級(jí)筆譯實(shí)務(wù)試題真題及答案
評(píng)論
0/150
提交評(píng)論