課程設計---ping程序設計與實現(xiàn)_第1頁
已閱讀1頁,還剩16頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、<p><b>  課 程 設 計</b></p><p>  課程名稱____計算機網(wǎng)絡_____</p><p>  題目名稱_Ping程序設計與實現(xiàn)</p><p>  學生學院____計算機學院____</p><p>  專業(yè)班級____08計科4班___ </p><p> 

2、 學 號____ ___</p><p>  2011 年 1 月 8 日</p><p><b>  一、 課程設計目的</b></p><p>  本次課程設計的目的旨在通過網(wǎng)絡相關(guān)程序的編寫,使我們能深入理解TCP/IP協(xié)議機制,以及初步掌握基于Winsocket的網(wǎng)絡編程技術(shù)。同時鞏固相關(guān)的理論知識,為以后

3、程序開發(fā)打下良好而又堅實的基礎。</p><p><b>  二、知識準備</b></p><p><b>  1、ICMP協(xié)議</b></p><p>  互聯(lián)網(wǎng)控制信息協(xié)議(Internet CONTROL Message Protocol),用于錯誤報告和調(diào)試。該協(xié)議是TCP/IP協(xié)議集中的一個子協(xié)議,屬于網(wǎng)絡層協(xié)議

4、,主要用于在主機與路由器之間傳遞控制信息,包括報告錯誤、交換受限控制和狀態(tài)信息等。當遇到IP數(shù)據(jù)無法訪問目標、IP路由器無法按當前的傳輸速率轉(zhuǎn)發(fā)數(shù)據(jù)包等情況時,會自動發(fā)送ICMP消息。我們可以通過Ping命令發(fā)送ICMP回應請求消息并記錄收到ICMP回應回復消息,通過這些消息來對網(wǎng)絡或主機的故障提供參考依據(jù)。</p><p>  常見ICMP報文有響應請求報文,目標不可到達、源抑制和超時報文,此外還有時間戳報文。

5、</p><p>  2、Ping工作原理</p><p>  Ping的原理就是首先建立通道,然后發(fā)送包,對方接受后返回信息,這個包至少包括以下內(nèi)容:發(fā)送的時候,包的內(nèi)容包括對方的ip地址和自己的地址,還有序列數(shù);回送的時候包括雙方地址,還有時間等,主要是接受方在都是在操作系統(tǒng)內(nèi)核里做好的,時刻在監(jiān)聽。Ping程序生成一個icmp“回送請求”,將其發(fā)送給目的主機。通過檢測是否可以收到目標

6、主機的應答,便可以知道網(wǎng)絡的連通性。</p><p>  (3) Tracert 工作原理</p><p>  透過向目標發(fā)送不同 IP 生存時間 (TTL) 值的ICMP回應數(shù)據(jù)包,Tracert 診斷程序確定到目標所采取的路由。要求路徑上的每個路由器在轉(zhuǎn)發(fā)數(shù)據(jù)包之前至少將數(shù)據(jù)包上的 TTL 遞減 1。數(shù)據(jù)包上的 TTL 減為 0 時,路由器應該將“ICMP已超時”的消息發(fā)回源系統(tǒng)。Tr

7、acert 先發(fā)送 TTL 為 1 的響應數(shù)據(jù)包,并在隨后的每次發(fā)送過程將 TTL 遞增1,直到目標響應或 TTL 達到最大值,從而確定路由。透過檢查中間路由器發(fā)回的“ICMP已超時”的消息確定路由。</p><p>  三、界面設計及數(shù)據(jù)結(jié)構(gòu)的說明</p><p>  1 、MFC界面設計建立流程</p><p>  步驟一:打開VC6.0,點擊文件選項,在pro

8、ject選項卡中選擇MFC Appwizard(exe),項目名稱為ping。</p><p>  步驟二:在新窗口中選擇窗口類型為基于對話框的類型。</p><p>  步驟三:設置界面選項</p><p>  步驟四:設置窗口類型</p><p>  步驟五:選擇相應類,點擊finish完成。</p><p>  

9、界面建立成功后添加相應按鈕及功能模塊。主界面設計如下:</p><p>  2、數(shù)據(jù)結(jié)構(gòu)的定義及說明</p><p><b>  (1)定義IP頭部</b></p><p>  typedef struct _IpHeader </p><p><b>  {</b></p><

10、p>  unsigned intHeaderLength:4;// 頭部長度</p><p>  unsigned intVersion:4;// IP版本號</p><p>  unsigned charTypeOfService;// 服務類型</p><p>  unsigned shortTotalLength;//

11、收發(fā)包的總長度</p><p>  unsigned shortIdentification;// 唯一校驗符</p><p>  unsigned shortFragmentationFlags; // 標志位</p><p>  unsigned char TTL;// 生存時間</p><p>  unsig

12、ned char Protocol; // 協(xié)議類型 (TCP, UDP 等)</p><p>  unsigned shortCheckSum;// IP頭部校驗和</p><p>  unsigned int sourceIPAddress;// 源地址</p><p>  unsigned int des

13、tIPAddress;// 目的地址</p><p>  } IpHeader;</p><p>  (2)定義ICMP頭部</p><p>  typedef struct _IcmpHeader</p><p><b>  {</b></p><p>  BYTEIcmpType;

14、 //icmp類型</p><p>  BYTEIcmpCode;//編碼類型 </p><p>  USHORTIcmpChecksum; //icmp校驗和</p><p>  USHORTIcmpId;</p><p>  USHORTIcmpSeq; //icmp序列號&

15、lt;/p><p>  ULONGIcmpTimestamp;// 頭部無標準定義,但仍需保留</p><p>  } IcmpHeader;</p><p><b>  (3)CIcmp類</b></p><p>  class CIcmp : public CSocket</p><p>

16、;<b>  {</b></p><p><b>  public:</b></p><p>  BOOL OpenNewSocket(HWND hWnd, unsigned int NotificationMessage, long NotifyEvents);</p><p>  BOOL OpenNewSocket(

17、HWND hWnd, unsigned int NotificationMessage, long NotifyEvents, int AFamily, int AType, int AProtocol);</p><p>  int CloseIcmpSocket(void);</p><p>  BOOL Connect(int ReceiveTimeout, int SendTime

18、out);</p><p>  BOOL Connect(LPINT ReceiveTimeout, LPINT SendTimeout, int AFamily, int AType, int AProtocol);</p><p>  int SetTTL(int TTL);</p><p>  int SetAsynchNotification(HWND hW

19、nd, unsigned int Message, long Events);</p><p>  int Receive(LPSTR pIcmpBuffer, int IcmpBufferSize);</p><p>  unsigned long GetIPAddress (LPSTR iHostName);</p><p>  int Ping (LPSTR

20、pIcmpBuffer, int IcmpBufferSize);</p><p>  unsigned short IcmpChecksum(unsigned short FAR *lpBuf, int Len);</p><p>  void DisplayError(CString ErrorType, CString FunctionName);</p><p&

21、gt;<b>  public:</b></p><p>  CIcmp(void);</p><p>  CIcmp(CIcmp &copy);</p><p>  ~CIcmp(void);</p><p><b>  private:</b></p><p>&

22、lt;b>  public:</b></p><p>  LPIcmpHeaderpIcmpHeader;</p><p>  LPIpHeaderpIpHeader;</p><p>  SOCKETicmpSocket;</p><p>  SOCKADDR_INicmpSockAddr;</p&

23、gt;<p>  SOCKADDR_INrcvSockAddr;</p><p>  DWORDicmpRoundTripTime;</p><p>  DWORDicmpPingSentAt;</p><p>  DWORDicmpPingReceivedAt;</p><p>  inticmpR

24、cvLen;</p><p>  inticmpHops;</p><p>  inticmpMaxHops;</p><p>  inticmpCurSeq;</p><p>  inticmpCurId;</p><p>  inticmpPingTimer;</p>&

25、lt;p>  inticmpSocketError;</p><p>  inticmpSocketErrorMod;</p><p>  unsigned longicmpHostAddress;</p><p>  protected:</p><p><b>  };</b></p>

26、;<p>  typedef CIcmp FAR * LPIcmp;</p><p>  (4)CPingPlusDlg類</p><p>  class CPingPlusDlg : public CDialog</p><p><b>  {</b></p><p>  enum ImageType&l

27、t;/p><p><b>  {</b></p><p>  Icon_Blank,</p><p>  Icon_BlueArrow</p><p><b>  };</b></p><p><b>  private:</b></p>&l

28、t;p>  void StopTimer();</p><p>  void StartTimer();</p><p>  void ChangeIconState(void);</p><p>  BOOL InitSockets();</p><p>  BOOL FetchWinsockSettings();</p>

29、<p>  BOOL LoadRegValues(void);</p><p>  void SaveRegValues();</p><p>  void SendPing(void);</p><p>  unsigned long HostIPAddress();</p><p>  void UpdateTrace ()

30、;</p><p>  void DisplayTrace(LPCSTR TripTimeMessage, LPCSTR IPAddressMessage, LPCSTR HostMessage);</p><p>  void EndTrace(void);</p><p>  void InitImageList();</p><p> 

31、 int AddListColumn(int column, int lfmt, int lmaxwidth, LPSTR ltext, int lsubitem);</p><p>  void DisplayBlankLine(void);</p><p>  void SetTraceSequence(int Seq, int FocusItem, ImageType FocusIm

32、age);</p><p>  void SetTraceFocus(int FocusItem, int FocusSubItem);</p><p>  void SetDisplayImage(int FocusItem, enum ImageType FocusImage);</p><p>  void TraceComment(CString Comme

33、nt);</p><p><b>  public:</b></p><p>  CPingPlusDlg(CWnd* pParent = NULL);// 標準構(gòu)造器</p><p>  protected:</p><p>  HICON m_hIcon;</p><p>  LRESUL

34、T OnPINGAsynch(WPARAM wParam, LPARAM lParam); </p><p><b>  public:</b></p><p>  CIcmp PingSocket; // Icmp 對象</p><p>  WSADATA wsaData; // Windows

35、 Socket 信息結(jié)構(gòu)</p><p>  CString LocalNameServer; </p><p>  CString LocalDomainName;// 域名 (從注冊機構(gòu)獲取)</p><p>  CString DefHost;// 默認主機名 (從注冊機構(gòu)獲取)</p><p>

36、  char HostName[MAXHOSTNAME];// 將主機名加入到會話中去</p><p>  char CurrentHostName[MAXHOSTNAME];// 當前正在ping的主機</p><p>  struct in_addr TraceTarget;// 操作路徑終端</p><p>  BOOL Timer

37、Active;// TRUE = 計時器到時</p><p>  unsigned longicmpIntervalCount;// 當前計時時間間距</p><p>  unsigned longicmpMaxIntervals;// 最大間距 </p><p>  charicmpBuffer[MAX_PACKET];// icm

38、p操作的普通緩沖區(qū)</p><p>  LPSTRpIcmpBuffer;// icmp緩沖區(qū)的故障分析報告指向</p><p>  inticmpDataLen;// icmp發(fā)出信息的字節(jié)數(shù) (不計算頭部)</p><p>  inticmpPingTTL;// 路徑操作所用到的ttl值</p><p>  BOO

39、LicmpTracing;// TRUE = 路徑操作, FALSE = PING操作</p><p>  BOOLPingSent;// TRUE = 等待ECHO回復, FALSE = 忽略輸入</p><p><b>  };</b></p><p>  四、程序主題功能設計模塊</p><p>  1、

40、調(diào)用ping模塊</p><p>  void CPingPlusDlg::OnPingButton() </p><p><b>  {</b></p><p>  IconState = 0;</p><p>  DisplayBlankLine ();</p><p>  icmpTraci

41、ng = FALSE;</p><p>  icmpPingTTL = PingSocket.icmpMaxHops; //ping生存時間為最大icmp跳數(shù)</p><p>  PingSocket.icmpCurSeq = 0;//當前icmp序列為0</p><p>  SendPing ( );//開始執(zhí)行ping</p><p>&

42、lt;b>  }</b></p><p>  2、初始化socket</p><p>  BOOL CPingPlusDlg::InitSockets()</p><p><b>  {</b></p><p>  if (!PingSocket.OpenNewSocket(GetSafeHwnd(),

43、</p><p>  WSA_PING_ASYNC, </p><p>  FD_READ | FD_WRITE,</p><p><b>  AF_INET,</b></p><p><b>  SOCK_RAW,</b></p><p>  IPPROTO_ICMP))&

44、lt;/p><p><b>  {</b></p><p>  PingSocket.DisplayError ("WSA_PING_ASYNC",</p><p>  "CPingPlusDlg::InitSockets");</p><p>  return FALSE;</

45、p><p><b>  }</b></p><p>  return TRUE;</p><p><b>  }</b></p><p>  3、獲取winsocket設置信息</p><p>  BOOL CPingPlusDlg::FetchWinsockSettings()

46、</p><p><b>  {</b></p><p>  SysTCPIPSTcpIp;</p><p>  if (!STcpIp.WinsockVersion(&wsaData))</p><p><b>  {</b></p><p>  MessageB

47、ox ("No valid winsock.dll detected",</p><p>  "CPingPlusDlg::OnInitDialog",</p><p>  MB_OK|MB_SYSTEMMODAL);</p><p>  return FALSE;</p><p><b> 

48、 }</b></p><p>  if (!STcpIp.GetLocalHostName (&m_LocalHost))</p><p><b>  {</b></p><p>  gethostname(CurrentHostName, MAXHOSTNAME);</p><p><b>

49、;  }</b></p><p><b>  else</b></p><p><b>  {</b></p><p>  memcpy (CurrentHostName, m_LocalHost, m_LocalHost.GetLength());</p><p>  CurrentH

50、ostName[m_LocalHost.GetLength()] = 0;</p><p><b>  }</b></p><p>  m_LocalHost = CurrentHostName;</p><p>  if (!STcpIp.GetDomainName(&LocalDomainName))</p><

51、p>  LocalDomainName = "";</p><p>  m_LocalHost += "." + LocalDomainName;</p><p>  memcpy (CurrentHostName, m_LocalHost, m_LocalHost.GetLength());</p><p>  Cur

52、rentHostName[m_LocalHost.GetLength()] = 0;</p><p>  if (!STcpIp.GetNSName (&LocalNameServer))</p><p>  LocalNameServer = "";</p><p>  m_NameServer = "Name Server:

53、 " + LocalNameServer;</p><p>  SetDlgItemText (IDC_LocalHost, m_LocalHost);</p><p>  SetDlgItemText (IDC_NameServer, m_NameServer);</p><p>  LoadRegValues();</p><p&g

54、t;  SetDlgItemText (IDC_DEST, HostName);</p><p>  return TRUE;</p><p><b>  }</b></p><p>  4、發(fā)送ping信息</p><p>  void CPingPlusDlg::SendPing(void)</p>&

55、lt;p><b>  {</b></p><p>  PingSent = TRUE;</p><p>  PingSocket.icmpCurSeq++;</p><p>  PingSocket.icmpCurId = (USHORT)GetCurrentProcessId();</p><p>  PingS

56、ocket.icmpHostAddress = HostIPAddress();</p><p>  if (PingSocket.icmpHostAddress == NULL)</p><p><b>  return;</b></p><p>  if (icmpTracing)</p><p><b>

57、  {</b></p><p>  icmpPingTTL++; }</p><p>  if (PingSocket.SetTTL (icmpPingTTL) == SOCKET_ERROR)</p><p>  { PingSocket.DisplayError ("setsocket(TTL)",</p>

58、<p>  "CPingPlusDlg::SendPing");</p><p>  return; }</p><p>  Sleep (100);//用藍色箭頭顯示序列號及相應信息</p><p>  SetTraceSequence (PingSocket.icmpCurSeq, </p><p>  

59、m_TraceList.GetItemCount(), </p><p>  Icon_BlueArrow);</p><p>  PingSocket.icmpSockAddr.sin_family = PF_INET;</p><p>  PingSocket.icmpSockAddr.sin_addr.s_addr = PingSocket.icmpHostA

60、ddress;</p><p>  PingSocket.icmpSockAddr.sin_port = 0;</p><p>  StartTimer();</p><p>  if (PingSocket.Ping (pIcmpBuffer, icmpDataLen) == SOCKET_ERROR)</p><p>  PingSock

61、et.DisplayError("Ping", "CPingPlusDlg::SendPing");</p><p><b>  }</b></p><p><b>  5、設置超時時間</b></p><p>  int CIcmp::SetTTL(int TTL)</p&g

62、t;<p><b>  {</b></p><p>  intResult;</p><p>  Result = setsockopt (icmpSocket, IPPROTO_IP, IP_TTL, (LPSTR)&TTL, sizeof(int));</p><p>  if (Result == SOCKET_E

63、RROR)</p><p><b>  {</b></p><p>  icmpSocketErrorMod = 1;</p><p>  icmpSocketError = WSAGetLastError();}</p><p>  return Result;}</p><p><b&

64、gt;  6、Ping函數(shù)</b></p><p>  int CIcmp::Ping (LPSTR pIcmpBuffer, int DataLen)</p><p><b>  {</b></p><p>  intResult;</p><p>  int IcmpBufferSize = DataL

65、en + IcmpHeaderLength;</p><p>  pIcmpHeader = (LPIcmpHeader)pIcmpBuffer;</p><p>  memset (pIcmpBuffer, 'E', IcmpBufferSize);</p><p>  memset (pIcmpHeader, 0, IcmpHeaderLengt

66、h);</p><p>  pIcmpHeader->IcmpType = ICMP_ECHO;</p><p>  pIcmpHeader->IcmpCode = 0;</p><p>  pIcmpHeader->IcmpChecksum = 0;</p><p>  pIcmpHeader->IcmpId = i

67、cmpCurId;</p><p>  pIcmpHeader->IcmpSeq = icmpCurSeq;</p><p>  pIcmpHeader->IcmpTimestamp = GetCurrentTime();</p><p>  pIcmpHeader->IcmpChecksum = IcmpChecksum ((USHORT FAR

68、 *)pIcmpBuffer,</p><p>  IcmpBufferSize);</p><p>  icmpPingSentAt = GetCurrentTime();</p><p>  Result = sendto (icmpSocket, </p><p>  pIcmpBuffer,</p><p> 

69、 IcmpBufferSize,</p><p><b>  0, </b></p><p>  (LPSOCKADDR)&icmpSockAddr, </p><p>  sizeof icmpSockAddr);</p><p>  if (Result == SOCKET_ERROR)</p>

70、<p>  { icmpSocketError = WSAGetLastError();</p><p>  icmpSocketErrorMod = 1;}</p><p>  return Result;}</p><p><b>  7、校驗和函數(shù)</b></p><p>  unsigned sh

71、ort CIcmp::IcmpChecksum(unsigned short FAR *lpBuf, int Len)</p><p><b>  {</b></p><p>  register long ChkSum = 0L;</p><p>  while (Len > 1)</p><p>  { C

72、hkSum += *(lpBuf++);</p><p>  Len -= sizeof (USHORT); }</p><p><b>  if (Len)</b></p><p>  ChkSum += *(UCHAR *)lpBuf;</p><p>  ChkSum = (ChkSum & 0xffff

73、) + (ChkSum>>16);</p><p>  ChkSum += (ChkSum >> 16);</p><p>  #pragma warning(disable : 4244)</p><p>  return (~ChkSum);</p><p>  #pragma warning(default :

74、4244)</p><p><b>  }</b></p><p>  8、Receive函數(shù)</p><p>  int CIcmp::Receive(LPSTR pIcmpBuffer, int IcmpBufferSize)</p><p><b>  {</b></p><

75、;p>  LPSOCKADDRpRcvSockAddr = (LPSOCKADDR)&rcvSockAddr;</p><p>  intResult;</p><p>  intRcvIpHdrLen;</p><p>  icmpPingReceivedAt = GetTickCount();</p><p&

76、gt;  icmpCurId = 0;</p><p>  rcvSockAddr.sin_family = AF_INET;</p><p>  rcvSockAddr.sin_addr.s_addr = INADDR_ANY;</p><p>  rcvSockAddr.sin_port = 0;</p><p>  RcvIpHdrLe

77、n = sizeof rcvSockAddr;</p><p>  Result = recvfrom (icmpSocket, </p><p>  pIcmpBuffer, </p><p>  IcmpBufferSize,</p><p><b>  0,</b></p><p>  pR

78、cvSockAddr,</p><p>  &RcvIpHdrLen);</p><p>  if (Result == SOCKET_ERROR)</p><p>  { icmpSocketError = WSAGetLastError();</p><p>  icmpSocketErrorMod = 1;</p>

79、<p>  DisplayError ("Receive","CIcmp::Receive");</p><p>  return Result;}</p><p>  icmpRcvLen = Result;</p><p>  pIpHeader = (LPIpHeader)pIcmpBuffer;</

80、p><p>  RcvIpHdrLen = pIpHeader->HeaderLength * 4;</p><p>  if (Result < RcvIpHdrLen + ICMP_MIN)</p><p><b>  {</b></p><p>  MessageBox(NULL, </p>

81、<p>  "Short message!", </p><p>  "CIcmp::Receive", </p><p>  MB_OK|MB_SYSTEMMODAL);</p><p>  icmpSocketErrorMod = 2;</p><p>  return Result;&l

82、t;/p><p><b>  }</b></p><p>  pIcmpHeader = (LPIcmpHeader)(pIcmpBuffer + RcvIpHdrLen);</p><p>  icmpCurId = pIcmpHeader->IcmpId;</p><p>  icmpRoundTripTime =

83、 icmpPingReceivedAt - pIcmpHeader->IcmpTimestamp;</p><p>  if (pIcmpHeader->IcmpType != ICMP_ECHOREPLY)</p><p><b>  {</b></p><p>  return Result;</p><p&

84、gt;<b>  }</b></p><p>  icmpCurSeq = pIcmpHeader->IcmpSeq;</p><p>  return Result;</p><p><b>  }</b></p><p><b>  五、運行結(jié)果</b></p&

85、gt;<p>  用ping命令測試本地主機的ip地址</p><p><b>  六、心得體會</b></p><p>  通過本次課程設計,我感覺到自己在編程方面,能力還十分欠缺。尤其是網(wǎng)絡編程方面,還有待提高。在以后的學習中應加強“內(nèi)功的修煉”。增強個人綜合素質(zhì)。為以后的就業(yè)打下堅實的基礎。</p><p><b>

溫馨提示

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

評論

0/150

提交評論