Chinaunix首页 | 论坛 | 博客
  • 博客访问: 29070
  • 博文数量: 25
  • 博客积分: 150
  • 博客等级: 入伍新兵
  • 技术积分: 160
  • 用 户 组: 普通用户
  • 注册时间: 2012-03-01 16:32
文章分类
文章存档

2012年(25)

我的朋友
最近访客

分类:

2012-03-01 17:17:08

原文地址:ping 程序源码 作者:yandaren_1220

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <string>
  4. #include <WinSock2.h>

  5. #pragma comment(lib, "ws2_32.lib")

  6. using namespace std;

  7. struct ICMPheader
  8. {
  9.     unsigned char    byType;
  10.     unsigned char    byCode;
  11.     unsigned short    nChecksum;
  12.     unsigned short    nId;
  13.     unsigned short    nSequence;
  14. };

  15. struct IPheader
  16. {
  17.     unsigned char    byVerLen;
  18.     unsigned char    byTos;
  19.     unsigned short    nTotalLength;
  20.     unsigned short    nId;
  21.     unsigned short    nOffset;
  22.     unsigned char    byTtl;
  23.     unsigned char    byProtocol;
  24.     unsigned short    nChecksum;
  25.     unsigned int    nSrcAddr;
  26.     unsigned int    nDestAddr;
  27. };

  28. unsigned short checkSum (char *pBuffer, int nLen)
  29. {
  30.     unsigned short nWord;
  31.     unsigned int nSum = 0;
  32.     int i;

  33.     //Make 16 bit words out of every two adjacent 8 bit words in the packet
  34.     //and add them up
  35.     for (i = 0; i < nLen; i = i + 2)
  36.     {
  37.         nWord =((pBuffer [i] << 8)& 0xFF00) + (pBuffer [i + 1] & 0xFF);
  38.         nSum = nSum + (unsigned int)nWord;    
  39.     }

  40.     //Take only 16 bits out of the 32 bit sum and add up the carries
  41.     while (nSum >> 16)
  42.     {
  43.         nSum = (nSum & 0xFFFF) + (nSum >> 16);
  44.     }

  45.     //One's complement the result
  46.     nSum = ~nSum;

  47.     return ((unsigned short) nSum);
  48. }

  49. int main()
  50. {
  51.     string str_dest_addr;
  52.     SOCKET sock_raw;
  53.     SOCKADDR_IN dest_addr;
  54.     SOCKADDR_IN from_addr;

  55.     char sendBuffer[1024] = {0};
  56.     char recvBuffer[1024] = {0};

  57.     WSADATA wsaData;

  58.     ::WSAStartup(MAKEWORD(2,2), &wsaData);

  59.     sock_raw = ::socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);

  60.     int timeout = 1000;

  61.     setsockopt(sock_raw, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout));
  62.     setsockopt(sock_raw, SOL_SOCKET, SO_SNDTIMEO, (char*)&timeout, sizeof(timeout));

  63.     dest_addr.sin_family = AF_INET;
  64.     memset(&dest_addr.sin_zero, 0, 8);

  65.     while( cout << "ping>")
  66.     {
  67.         cin >> str_dest_addr;
  68.         int nSeq = 0;
  69.         int nPacketSent = 0;
  70.         int nPacketReceived = 0;
  71.         int nTotalRoundTime = 0;
  72.         int nMaxRoundTime = 0;
  73.         int nMinRoundTime = -1;
  74.         if((dest_addr.sin_addr.S_un.S_addr = inet_addr(str_dest_addr.c_str())) == INADDR_NONE)
  75.         {
  76.             struct hostent *hp = NULL;
  77.             if((hp = gethostbyname(str_dest_addr.c_str())) != NULL)
  78.             {
  79.                 memcpy(&(dest_addr.sin_addr), hp->h_addr_list[0],hp->h_length);
  80.             }
  81.             else
  82.             {
  83.                 cout << "can not find the host!" << endl;
  84.                 continue;
  85.             }
  86.         }

  87.         while( nPacketSent < 4)
  88.         {
  89.             nPacketSent++;
  90.             ICMPheader* pIcmpHeader = (ICMPheader*)sendBuffer;

  91.             pIcmpHeader->byType = 8;
  92.             pIcmpHeader->byCode = 0;
  93.             pIcmpHeader->nId = (USHORT)::GetCurrentProcessId();
  94.             pIcmpHeader->nChecksum = 0;
  95.         
  96.             pIcmpHeader->nSequence = htons(nSeq++);
  97.             memset(sendBuffer + sizeof(ICMPheader), '*', 32);
  98.             pIcmpHeader->nChecksum = htons(checkSum(sendBuffer, sizeof(ICMPheader) + 32));
  99.             
  100.             int nRet = sendto(sock_raw, sendBuffer, sizeof(ICMPheader) + 32, 0, (SOCKADDR*)&dest_addr, sizeof(SOCKADDR_IN));

  101.             if(nRet == SOCKET_ERROR)
  102.             {
  103.                 cout << "send error:" << ::WSAGetLastError() << endl;
  104.                 break;
  105.             }

  106.             unsigned long dwSendTime = ::GetTickCount();

  107.             int fromLen = sizeof(SOCKADDR_IN);

  108.             nRet = recvfrom(sock_raw, recvBuffer, 1024, 0, (SOCKADDR*)&from_addr,&fromLen);

  109.             if(nRet == SOCKET_ERROR)
  110.             {
  111.                 if(::WSAGetLastError() == WSAETIMEDOUT)
  112.                 {
  113.                     cout << "Request time out" << endl;
  114.                     continue;
  115.                 }

  116.                 break;
  117.             }

  118.             IPheader* ipHdr = (IPheader*)recvBuffer;
  119.             ICMPheader* icmpHdrRet = (ICMPheader*)(recvBuffer + sizeof(IPheader));

  120.             if( icmpHdrRet->byCode == 0 &&
  121.                 icmpHdrRet->nId == pIcmpHeader->nId &&
  122.                 icmpHdrRet->nSequence == pIcmpHeader->nSequence)
  123.             {

  124.                 nPacketReceived++;
  125.                 unsigned long dwRecvTime = ::GetTickCount();
  126.                 int nRoundTime = dwRecvTime - dwSendTime;
  127.                 nTotalRoundTime += nRoundTime;

  128.                 if(nMinRoundTime == -1)
  129.                 {
  130.                     nMinRoundTime = nRoundTime;
  131.                     nMaxRoundTime = nRoundTime;
  132.                 }

  133.                 if( nRoundTime < nMinRoundTime)
  134.                 {
  135.                     nMinRoundTime = nRoundTime;
  136.                 }
  137.                 
  138.                 if( nRoundTime > nMaxRoundTime)
  139.                 {
  140.                     nMaxRoundTime = nRoundTime;
  141.                 }
  142.             

  143.                 cout << "Reply from " << inet_ntoa(from_addr.sin_addr) << ": bytes = " << nRet - sizeof(ICMPheader) - sizeof(IPheader) << ", time = " << nRoundTime << "ms, TTL = " << (int)ipHdr->byTtl << endl;
  144.             }
  145.             else
  146.             {
  147.                 cout << "The echo reply is not correct!" << endl;
  148.             }

  149.             Sleep(1000);
  150.         }


  151.         cout << endl << "Ping statistics for " << inet_ntoa(from_addr.sin_addr) << ":" << endl << "\t" << "Packets:sent = " << nPacketSent << ", Received = "
  152.             << nPacketReceived << ", Lost = " << (nPacketSent - nPacketReceived) << "(" << ((float)(nPacketSent - nPacketReceived) /nPacketSent) * 100 << "% loss)" << endl;

  153.         if(nPacketReceived)
  154.         {
  155.             cout << "\rApproximate round trip times in milli-seconds:" << endl << '\t' << "Minimum = " << nMinRoundTime <<
  156.             "ms, Maximum = " << nMaxRoundTime << "ms, Average = " << (float)nTotalRoundTime /nPacketReceived << "ms" << endl;
  157.         }

  158.     }

  159.     ::closesocket(sock_raw);
  160.     ::WSACleanup();

  161.     return 0;
  162. }
阅读(499) | 评论(0) | 转发(0) |
0

上一篇:VC运行程序文件

下一篇:VC++多线程编程

给主人留下些什么吧!~~