2023年全國碩士研究生考試考研英語一試題真題(含答案詳解+作文范文)_第1頁
已閱讀1頁,還剩12頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

1、<p>  計(jì)算機(jī)網(wǎng)絡(luò)工程課程設(shè)計(jì)報(bào)告</p><p>  題 目: Ping程序的實(shí)現(xiàn) </p><p>  學(xué)生姓名: </p><p>  學(xué) 號: </p><p>  專業(yè)班級: 計(jì)科專業(yè)10102班 </p&

2、gt;<p>  同組姓名:   </p><p>  指導(dǎo)教師: </p><p>  設(shè)計(jì)時(shí)間: 2013年下學(xué)期第16周 </p><p><b>  目錄</b></p><p>  一、課程設(shè)計(jì)的目的和意義2</p&g

3、t;<p>  二、課程設(shè)計(jì)的內(nèi)容和要求2</p><p><b>  1.內(nèi)容:2</b></p><p><b>  2.要求:2</b></p><p>  三、課程設(shè)計(jì)的相關(guān)技術(shù)2</p><p>  四、課程設(shè)計(jì)過程2</p><p>  1

4、.Ping主模塊2</p><p>  2.功能控制模塊4</p><p>  3.數(shù)據(jù)報(bào)解析模塊5</p><p>  五、課程設(shè)計(jì)小結(jié)6</p><p><b>  六、參考文獻(xiàn)7</b></p><p>  七、附 錄(程序清單)7</p><p>&

5、lt;b>  八、心得體會11</b></p><p>  一、課程設(shè)計(jì)的目的和意義</p><p>  利用ICMP數(shù)據(jù)包、C語言實(shí)現(xiàn)Ping命令程序,能實(shí)現(xiàn)基本的Ping操作,發(fā)送ICMP回顯請求報(bào)文,用于測試—個主機(jī)到只一個主機(jī)之間的連通情況。通過本程序的訓(xùn)練,使學(xué)生熟悉ICMP報(bào)文結(jié)構(gòu),使學(xué)生對ICMP有更深的理解,掌握Ping程序的設(shè)計(jì)方法,掌握網(wǎng)絡(luò)編程的方法

6、和技巧,從而編寫出功能更強(qiáng)大的程序。</p><p>  二、課程設(shè)計(jì)的內(nèi)容和要求</p><p><b>  1.內(nèi)容:</b></p><p>  用C語言實(shí)現(xiàn)Ping命令程序,能實(shí)現(xiàn)基本的Ping操作,發(fā)送ICMP回顯請求報(bào)文,用于測試—個主機(jī)到只一個主機(jī)之間的連通情況。</p><p><b>  2.

7、要求: </b></p><p>  獨(dú)立完成程序的設(shè)計(jì)、編碼和調(diào)試。</p><p>  系統(tǒng)利用C語言實(shí)現(xiàn),程序調(diào)試環(huán)境為Turbo C或VC;</p><p>  按照課程設(shè)計(jì)規(guī)范書寫課程設(shè)計(jì)報(bào)告。</p><p>  采用VC環(huán)境進(jìn)行調(diào)試運(yùn)行。</p><p>  三、課程設(shè)計(jì)的相關(guān)技術(shù)</p

8、><p>  由于Ping程序是面向用戶的應(yīng)用程序,該程序使用ICMP的封裝機(jī)制,通過IP協(xié)議來工作。為了實(shí)現(xiàn)直接對IP和ICMP包進(jìn)行操作,實(shí)驗(yàn)中使用RAW模式的socket編程。首先定義IP數(shù)據(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ù)DecodeICMPHead

9、er()、釋放資源函Cleanup()。最后主函數(shù)通過調(diào)用這些函數(shù)來實(shí)現(xiàn)Ping命令功能。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í)可能會遇到阻塞或者目標(biāo)主機(jī)不通,造成超時(shí),因此需要在發(fā)送數(shù)據(jù)包后調(diào)用一個函數(shù)判斷是否超時(shí),此處調(diào)

10、用庫函數(shù)setsockopt()來實(shí)現(xiàn)超時(shí)判斷;其次,校驗(yàn)和函數(shù)采用移位方法進(jìn)行計(jì)算。</p><p>  套接字所需要的文件有頭文件Winsocket2.h、庫文件WS2_32.LIB、動態(tài)庫W32_32.DLL。創(chuàng)建套接字的時(shí)候參數(shù)的以及在創(chuàng)建套接字之前必須首先使用WSAStartup函數(shù)。</p><p><b>  四、課程設(shè)計(jì)過程</b></p>

11、<p><b>  1.Ping主模塊</b></p><p>  Ping()函數(shù)是本程序的核心部分,它基本是調(diào)用其他模塊的函數(shù)來實(shí)現(xiàn)最終功能,其主要布驟包括:定義及初始化各個全局變量、打開socket動態(tài)庫、設(shè)置接收和發(fā)送超時(shí)值、域名地址解析、分配內(nèi)存、創(chuàng)建及初始化ICMP報(bào)文、發(fā)送ICMP請求報(bào)文、接收ICMP 應(yīng)答報(bào)文以及解讀應(yīng)答報(bào)文和輸出Ping結(jié)果,最后釋放占用的資

12、源其流程如下頁圖2.1所示。</p><p><b>  注釋:</b></p><p>  該模塊并非只有處理還包括判斷及輸出判斷結(jié)果的含義;</p><p>  程序沒運(yùn)行一次就只能輸出四行結(jié)果(前提是輸入的地址有效),欲再次PING其他地址必須要重新啟動程序。</p><p>  輸入時(shí)不能輸入目標(biāo)主機(jī)名,不然pi

13、ng結(jié)果為TIMEOUT;</p><p><b>  2.功能控制模塊</b></p><p>  功能控制模塊主要是為其他模塊提供可調(diào)用的函數(shù),該模塊主要包括參數(shù)獲取功能、計(jì)算ICMP數(shù)據(jù)報(bào)文檢驗(yàn)和、清除SOCKET,ICMP包數(shù)據(jù)以及接受緩沖區(qū)、占用資源釋放功能和顯示用尸幫助功能。該模塊一共包含三個函數(shù)來實(shí)現(xiàn)。,流程如圖2.2所示。</p><

14、;p>  圖2.2 功能控制模塊</p><p><b>  注釋:</b></p><p>  a.illICMPData是由一系列的初始化的語句在流程圖中不再畫出;</p><p>  b.Cleanup()函數(shù)中的WSACleanup(),HeapFree(),closesocket()都是一些庫函數(shù)。checksum()校驗(yàn)和函

15、數(shù)是冗余校驗(yàn)的一種形式。 它是通過錯誤檢測方法,對經(jīng)過空間(如通信)或者時(shí)間(如計(jì)算機(jī)存儲)傳送的數(shù)據(jù)的完整性進(jìn)行檢查的一種簡單方法。</p><p><b>  3.數(shù)據(jù)報(bào)解析模塊</b></p><p>  數(shù)據(jù)報(bào)解析模塊提供了解讀IP選項(xiàng)和解讀IcMP報(bào)文的功能。從本機(jī)收到目的主機(jī)返回的1cMP回顯應(yīng)答報(bào)文,就開始逐個地解讀IcMP報(bào)文,如果需要記錄路由的情況下

16、,IcMP解析函數(shù)將調(diào)用IP選項(xiàng)解讀函數(shù)來實(shí)現(xiàn)IP路由的輸出(但本程序沒有此功能。該模塊主要由DecodeICMPHeader一個函數(shù)來實(shí)現(xiàn),而中間也會調(diào)用其它模塊的相應(yīng)函數(shù)。其流程圖如圖2.3:</p><p><b>  注釋:</b></p><p>  a.判斷是否為我們所要的數(shù)據(jù)報(bào)回應(yīng)之前,還有一些判斷回應(yīng)多少內(nèi)容的語句未呈現(xiàn)出;</p>&l

17、t;p>  b.函數(shù)GetTickCount()是用來記錄此時(shí)我機(jī)所處的現(xiàn)在時(shí)間(毫秒級);</p><p>  圖2.3 數(shù)據(jù)報(bào)解析模塊</p><p><b>  五、課程設(shè)計(jì)小結(jié)</b></p><p>  1.運(yùn)行操作結(jié)果:在vc里運(yùn)行之后界面:</p><p>  2.輸入本機(jī)ip地址:</p&g

18、t;<p>  3.輸入網(wǎng)上ip看結(jié)果:</p><p>  4. 但是當(dāng)網(wǎng)絡(luò)連不通時(shí),就會出現(xiàn)下圖結(jié)果</p><p><b>  六、參考文獻(xiàn)</b></p><p>  【1】Visual C++網(wǎng)絡(luò)通信編程實(shí)用案例精選(第二版)曹衍龍 劉海英 編著;</p><p>  【2】Windows網(wǎng)絡(luò)

19、編程技術(shù) (美);</p><p>  七、附 錄(程序清單)</p><p>  #pragma comment(lib,"ws2_32.lib")</p><p>  #include <winsock2.h>//創(chuàng)建套接字頭文件</p><p>  #include <ws2tcpip.h>

20、;</p><p>  #include <stdio.h>//標(biāo)準(zhǔn)輸入輸出函數(shù)</p><p>  #include <stdlib.h>//實(shí)用程序庫函數(shù)</p><p>  #include <string.h></p><p>  typedef struct iphdr </p>&

21、lt;p><b>  {</b></p><p>  unsigned int h_len:4; // 頭長度</p><p>  unsigned int version:4; // IP版本 </p><p>  unsigned char service;

22、 // 服務(wù)類型 </p><p>  unsigned short total_len; // 包的總長度 </p><p>  unsigned short ident; // 包標(biāo)示身份 </p><p>  unsig

23、ned short frag_and_flags; // 標(biāo)志 </p><p>  unsigned char ttl; // 包生命周期 </p><p>  unsigned char proto; // 協(xié)議類型 </p><p>  unsigne

24、d short checksum; // IP 校驗(yàn) </p><p>  unsigned int sourceIP; //源IP</p><p>  unsigned int destIP; //目標(biāo)IP</p><p>  } IpHeader;</p><p>  #defin

25、e ICMP_ECHO 8 //ICMP報(bào)文類型,回顯請求 </p><p>  #define ICMP_ECHOREPLY 0 //ICMP報(bào)文類型,回顯應(yīng)答</p><p>  #define ICMP_MIN 8 //最小的ICMP數(shù)據(jù)報(bào)大小 </p

26、><p>  typedef struct icmphdr </p><p><b>  {</b></p><p>  BYTE i_type; //ICMP報(bào)文類型</p><p>  BYTE i_code; //該類型中的代碼號</p>

27、;<p>  USHORT i_cksum; //校驗(yàn)和</p><p>  USHORT i_id; //惟一的標(biāo)識符</p><p>  USHORT i_seq; //序列號</p><p>  ULONG timestamp;

28、 //時(shí)間戳 </p><p>  } IcmpHeader;</p><p>  #define DEF_PACKET_SIZE 32 //默認(rèn)數(shù)據(jù)報(bào)大小</p><p>  #define MAX_PACKET 1024 // 最大的ICMP數(shù)據(jù)報(bào)大小 </p><p>  

29、#define MAX_IP_HDR_SIZE 60 // 最大IP頭長度 </p><p>  //初始化全局變量 </p><p>  int datasize=DEF_PACKET_SIZE; </p><p>  char *icmp_data=NULL;</p><p>  c

30、har *recvbuf=NULL; </p><p>  SOCKET m_hSocket= INVALID_SOCKET; </p><p>  char *lpdest=NULL;</p><p>  //填充ICMP數(shù)據(jù)報(bào)字段函數(shù)</p><p>  void FillICMPData(char *icmp_data, int dat

31、asize)</p><p><b>  {</b></p><p>  IcmpHeader *icmp_hdr = NULL; </p><p>  char*datapart = NULL;</p><p>  icmp_hdr = (IcmpHeader*)icmp_data; </p><p

32、>  icmp_hdr->i_type = ICMP_ECHO; </p><p>  icmp_hdr->i_code = 0; </p><p>  icmp_hdr->i_id = (USHORT)GetCurrentProcessId();</p><p>  icmp_hdr->i_cksum = 0; <

33、/p><p>  icmp_hdr->i_seq = 0;</p><p>  datapart = icmp_data + sizeof(IcmpHeader);</p><p><b>  }</b></p><p><b>  //校驗(yàn)和函數(shù)</b></p><p>

34、  USHORT checksum(USHORT *buffer, int size)</p><p>  { unsigned long cksum=0;</p><p>  while (size > 1) </p><p>  { cksum += *buffer++; size -= sizeof(USHORT); }</p>

35、;<p>  if (size) </p><p>  { cksum += *(UCHAR*)buffer; } </p><p>  cksum = (cksum >> 16) + (cksum & 0xffff); </p><p>  cksum += (cksum >>16);return (USHORT

36、)(~cksum);</p><p><b>  }</b></p><p>  //解讀ICMP報(bào)首部函數(shù)</p><p>  void DecodeICMPHeader(char *buf, int bytes, SOCKADDR_IN *from)</p><p><b>  {</b><

37、;/p><p>  IpHeader*iphdr = NULL; </p><p>  IcmpHeader*icmphdr = NULL;</p><p>  unsigned short iphdrlen;</p><p>  DWORD tick; </p><p>  static int icmpcoun

38、t = 0;</p><p>  iphdr = (IpHeader *)buf; </p><p>  iphdrlen = iphdr->h_len * 4; </p><p>  tick = GetTickCount();</p><p>  if (bytes < iphdrlen + ICMP_MIN) </

39、p><p>  { printf("Too few bytes from %s \r\n",inet_ntoa(from->sin_addr)); }</p><p>  icmphdr = (IcmpHeader*)(buf + iphdrlen);</p><p>  if (icmphdr->i_type != ICMP_E

40、CHOREPLY) </p><p>  { printf("nonecho type %d received \r\n", icmphdr->i_type); }</p><p>  if (icmphdr->i_id != (USHORT)GetCurrentProcessId()) </p><p>  { printf(

41、"其他程序的回應(yīng)報(bào)文! \t錯誤代碼 %d\n", WSAGetLastError()); }</p><p>  DWORD tick0[4]; </p><p>  tick0[icmpcount]=tick - icmphdr->timestamp;</p><p>  if(tick0[icmpcount]<1)</

42、p><p>  printf("Replyfrom %s: bytes=%d time<1ms </p><p>  icmp_seq=%d\n",inet_ntoa(from->sin_addr), bytes, icmphdr->i_seq );</p><p><b>  else </b></

43、p><p>  printf("Reply from %s: bytes=%d time=%dms icmp_seq = %d\n",inet_ntoa(from->sin_addr), bytes,tick0[icmpcount], icmphdr->i_seq); </p><p>  icmpcount++;</p><p><

44、;b>  }</b></p><p><b>  //釋放資源函數(shù)</b></p><p>  void Cleanup()</p><p><b>  {</b></p><p>  if (m_hSocket != INVALID_SOCKET) </p><

45、;p>  closesocket(m_hSocket);</p><p>  HeapFree(GetProcessHeap(), 0, recvbuf);</p><p>  HeapFree(GetProcessHeap(), 0, icmp_data); </p><p>  WSACleanup();</p><p><b

46、>  }</b></p><p><b>  //主函數(shù)</b></p><p>  void main()</p><p><b>  {</b></p><p>  WSADATA wsaData; char a[100]; printf("ping &qu

47、ot;);</p><p>  scanf("%s",a); lpdest=a; SOCKADDR_IN m_addrDest;//結(jié)構(gòu)體 </p><p>  SOCKADDR_IN m_addrFrom; int timeout=1000; USHORT seq_no=0;</p><p>  if (WSAStartu

48、p(MAKEWORD(2, 2), &wsaData) != 0)</p><p>  { printf("Sorry, you cannot load socket dll!"); }</p><p>  m_hSocket = WSASocket (AF_INET, SOCK_RAW, IPPROTO_ICMP, NULL, 0,WSA_FLAG_OVE

49、RLAPPED);//創(chuàng)建原始套接字,該套接字用于ICMP協(xié)議</p><p>  if (m_hSocket == INVALID_SOCKET) //如果套接字創(chuàng)建不成功</p><p>  { printf("socket 創(chuàng)建失敗!"); }</p><p>  int bread = setsockopt(m_hSocket, SO

50、L_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout));//設(shè)置接收的超時(shí)值</p><p>  if(bread == SOCKET_ERROR) </p><p>  { printf("設(shè)置socket接收超時(shí)選項(xiàng)錯誤!"); }</p><p>  timeout =

51、1000;</p><p>  bread = setsockopt(m_hSocket, SOL_SOCKET, SO_SNDTIMEO, (char*)&timeout, sizeof(timeout));//設(shè)置發(fā)送的超時(shí)值</p><p>  if (bread == SOCKET_ERROR) </p><p>  { printf("

52、設(shè)置socket發(fā)送超時(shí)選項(xiàng)錯誤!"); }</p><p>  memset(&m_addrDest, 0, sizeof(m_addrDest));// 用0初始化目的地地址</p><p>  m_addrDest.sin_family = AF_INET;//設(shè)置地址族,這里表示使用IP地址族</p><p>  if ((m_addrD

53、est.sin_addr.s_addr = inet_addr(lpdest)) == INADDR_NONE)//地址轉(zhuǎn)化</p><p><b>  { </b></p><p>  struct hostent *hp = NULL;</p><p>  if ((hp = gethostbyname(lpdest)) != NULL

54、) //名字解析,根據(jù)主機(jī)名獲取IP地址</p><p><b>  {</b></p><p>  memcpy(&(m_addrDest.sin_addr), hp->h_addr, hp->h_length);//將獲取到的IP值賦給目的地地址中的相應(yīng)字段</p><p>  m_addrDest.sin_fam

55、ily = hp->h_addrtype; //將獲取到的地址族值賦給目的地地址中的相應(yīng)字段</p><p><b>  }</b></p><p><b>  else</b></p><p><b>  {</b></p><p>  printf("

56、不能找到名為 %s 的主機(jī)\t錯誤代碼 %d\n",lpdest, exit(0);</p><p>  } } </p><p>  printf("Pinging %s with 64 bytes of data: \n\n", inet_ntoa(m_addrDest.sin_addr)); </p><p

57、>  datasize += sizeof(IcmpHeader); //數(shù)據(jù)報(bào)文大小需要包含ICMP報(bào)頭</p><p>  //根據(jù)默認(rèn)堆句柄,從堆中分配MAX_PACKET內(nèi)存塊,新分配內(nèi)存的內(nèi)容將被初始化為0</p><p>  icmp_data=(char*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,MAX_PACKET);

58、</p><p>  recvbuf =(char*) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,MAX_PACKET);</p><p>  if (!icmp_data) //如果分配內(nèi)存不成功</p><p>  { printf("堆分配錯誤!"); }</p><p

59、>  memset(icmp_data,0,MAX_PACKET);//創(chuàng)建ICMP報(bào)文</p><p>  FillICMPData(icmp_data,datasize);</p><p>  // 開始發(fā)送或接受ICMP包</p><p>  int nCount=0;</p><p><b>  while(1) &l

60、t;/b></p><p>  { int bwrote; </p><p>  if(nCount++ == 4) </p><p>  break;//超過指定的記錄條數(shù)則退出</p><p>  ((IcmpHeader*)icmp_data)->i_cksum = 0;//計(jì)算校驗(yàn)和前要把校驗(yàn)和字段設(shè)置為

61、0</p><p>  ((IcmpHeader*)icmp_data)->timestamp = GetTickCount();//獲取操作系統(tǒng)啟動到現(xiàn)在所經(jīng)過的毫秒數(shù),設(shè)置時(shí)間戳</p><p>  ((IcmpHeader*)icmp_data)->i_seq = seq_no++;//設(shè)置序列號</p><p>  ((IcmpHeader*)i

62、cmp_data)->i_cksum = checksum((USHORT*)icmp_data, datasize);//計(jì)算校驗(yàn)和</p><p>  bwrote = sendto(m_hSocket, icmp_data, datasize, 0, (struct sockaddr*)&m_addrDest, sizeof(m_addrDest));//開始發(fā)送ICMP請求</p>

63、;<p>  if (bwrote == SOCKET_ERROR)//如果發(fā)送不成功</p><p><b>  {</b></p><p>  if (WSAGetLastError() == WSAETIMEDOUT) //如果是由于超時(shí)不成功</p><p>  { printf("Requrest timed

64、 out ! \r\n"); continue; }</p><p>  printf("目標(biāo)不可達(dá)!\t錯誤代碼 %d\n", WSAGetLastError());//其他發(fā)送不成功原因</p><p>  continue; }</p><p>  if (bwrote < datasize) </p>

65、<p>  {printf("Wrote %d bytes \r\n", bwrote); }</p><p>  int fromlen = sizeof(m_addrFrom);//開始接收ICMP應(yīng)答</p><p>  bread=recvfrom(m_hSocket,recvbuf,MAX_PACKET,0,(struct sockaddr*

66、)&m_addrFrom, &fromlen);</p><p>  if (bread == SOCKET_ERROR)//如果接收不成功</p><p><b>  {</b></p><p>  if (WSAGetLastError() == WSAETIMEDOUT) //如果是由于超時(shí)不成功</p>&

67、lt;p>  { printf("Requrest timed out !\r\n"); continue; } printf("接收數(shù)據(jù)函數(shù)調(diào)用錯誤!\t錯誤代碼 %d\n", WSAGetLastError());//其他接收不成功原因</p><p><b>  exit(0);</b></p><

68、;p><b>  }</b></p><p>  DecodeICMPHeader(recvbuf, bread, &m_addrFrom);//解讀接收到的ICMP數(shù)據(jù)報(bào)</p><p>  } Cleanup();</p><p><b>  }</b></p><p><b

溫馨提示

  • 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. 眾賞文庫僅提供信息存儲空間,僅對用戶上傳內(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

提交評論