TWPing.h 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. #pragma once
  2. #include <iostream>
  3. #include <iomanip>
  4. #include <fstream>
  5. #include <winsock2.h>
  6. #include <ws2tcpip.h>
  7. #include <stdio.h>
  8. #include <tchar.h>
  9. #include <stdarg.h>
  10. #include <string>
  11. #include <vector>
  12. #include <assert.h>
  13. #include <windows.h>
  14. #include <time.h>
  15. #include <atlbase.h>
  16. #include <conio.h>
  17. #include "mbnapi.h"
  18. #include <comdef.h>
  19. #include <IPHlpApi.h> //for mobileDial
  20. #pragma comment(lib, "ws2_32.lib")
  21. #pragma comment(lib, "mbnapi_uuid.lib")
  22. #include "SpBase.h"
  23. #if defined(SPBASE_API)
  24. #define printf(fmt, ...) \
  25. Dbg(fmt, __VA_ARGS__)
  26. #else
  27. #define printf(fmt, ...) \
  28. printf(fmt "\n", __VA_ARGS__)
  29. #endif
  30. //路由选项类型,占用3字节
  31. #define IP_RECORD_ROUTE 0x7
  32. //IP时间戳选项
  33. #define IP_TIMESTAMP 0x44
  34. #define DEFAULT_PACKET_SIZE 32
  35. #define MAX_PACKET 1024 + 12 + 20 + 1
  36. #define MAX_IP_HDR_SIZE 60
  37. //回送请求或回答
  38. #define ICMP_ECHO 8
  39. #define ICMP_ECHO_REPLY 0
  40. #define MAX_UNSIGNED_SHORT 65535
  41. #define DEFAULT_TIMEOUT 3000
  42. #define DEFAULT_INTERVAL 1000
  43. typedef struct _iphdr
  44. {
  45. //注意顺序,网络字节序,大端
  46. unsigned int h_len:4;
  47. unsigned int version:4;
  48. unsigned char tos; // type of service
  49. unsigned short total_len; // Total length of the packet
  50. unsigned short ident; // Unique identifier
  51. unsigned short frag_and_flags; // 标志和片偏移
  52. unsigned char ttl; // time to live
  53. unsigned char proto;
  54. unsigned short checksum;
  55. unsigned int sourceIP;
  56. unsigned int destIP;
  57. }IpHeader;
  58. #define DEFAULT_IP_HEAD_SIZE 20
  59. typedef struct _icmphdr
  60. {
  61. BYTE btType; //type of icmp
  62. BYTE btCode; // code of icmp 进一步定义查询或消息的类型 默认0
  63. USHORT usCksum; //16bits 对ICMP头内容的一个补余求和
  64. USHORT usId; //identification
  65. USHORT usSeq;
  66. //选项值
  67. ULONG ulTimestamp;
  68. }IcmpHeader;
  69. #define DEFAULT_ICMP_HEAD_SIZE sizeof(IcmpHeader)
  70. const double MAX_GSM_SIGNAL_STRENGTH = 31.0;
  71. class CTWPing
  72. {
  73. public:
  74. CTWPing();
  75. ~CTWPing(void);
  76. int Initial(const char* destIp, int nDataSize = 0, int nTimeout = 0, int nInterval = 0);
  77. //0 结束成功返回
  78. //1 创建套接字失败
  79. //2 超时达上限
  80. //3 其他错误达到上限
  81. int Ping();
  82. //0 结束成功返回
  83. //1 创建套接字失败
  84. //2 超时
  85. //3 其他错误
  86. //4 无效需要重新尝试
  87. int PingOnce();
  88. void TerminatePing()
  89. {
  90. m_bCancelPing = TRUE;
  91. }
  92. SOCKET m_hSocket;
  93. SOCKADDR_IN m_addrDest;
  94. SOCKADDR_IN m_addrSource;
  95. void Cleanup(bool bWSACleanup = false) //Consistent with FSM -Josephus@2017823 11:09:38
  96. {
  97. if(m_hSocket != INVALID_SOCKET)
  98. {
  99. closesocket(m_hSocket);
  100. m_hSocket = INVALID_SOCKET;
  101. }
  102. if(m_recvBuf != NULL)
  103. {
  104. HeapFree(GetProcessHeap(), 0, m_recvBuf);
  105. m_recvBuf = NULL;
  106. }
  107. if(m_icmpData != NULL)
  108. {
  109. HeapFree(GetProcessHeap(), 0, m_icmpData);
  110. m_icmpData = NULL;
  111. }
  112. while(bWSACleanup && TRUE)
  113. {
  114. if(WSACleanup() != ERROR_SUCCESS && WSAGetLastError() == WSANOTINITIALISED)
  115. break;
  116. }
  117. m_bInited = false;
  118. }
  119. bool IsValid() const
  120. {
  121. return m_bInited;
  122. }
  123. private:
  124. int m_nDataSize;
  125. int m_nTimeout;
  126. int m_nInterval;
  127. char m_szIP[128];
  128. char* m_icmpData;
  129. char* m_recvBuf;
  130. BOOL m_bCancelPing;
  131. bool m_bInited;
  132. USHORT m_usPacketSeqNo;
  133. USHORT GetCurrentSeqNo()
  134. {
  135. return m_usPacketSeqNo;
  136. }
  137. USHORT IncreaseCurSeqNo()
  138. {
  139. if(m_usPacketSeqNo < MAX_UNSIGNED_SHORT)
  140. {
  141. m_usPacketSeqNo++;
  142. }
  143. else
  144. {
  145. m_usPacketSeqNo = 0;
  146. }
  147. return m_usPacketSeqNo;
  148. }
  149. int InitICMPData();
  150. //-1 重置套接字并重新发送
  151. //-2 重新接收
  152. int DecodeICMPData(int bytes);
  153. int CreateSocket()
  154. {
  155. if(m_hSocket != INVALID_SOCKET)
  156. {
  157. closesocket(m_hSocket);
  158. m_hSocket = INVALID_SOCKET;
  159. }
  160. m_hSocket = WSASocket(AF_INET, SOCK_RAW, IPPROTO_ICMP, NULL, 0, WSA_FLAG_OVERLAPPED);
  161. if(m_hSocket == INVALID_SOCKET)
  162. {
  163. printf("WSASocket() failed with status %d", WSAGetLastError());
  164. return -1;
  165. }
  166. int bread = setsockopt(m_hSocket, SOL_SOCKET, SO_SNDTIMEO, (char*)&m_nTimeout, sizeof(m_nTimeout));
  167. if(bread == SOCKET_ERROR)
  168. {
  169. printf("Warning: Setsockopt(SO_SNDTIMEO) failed with status %d", WSAGetLastError());
  170. }
  171. bread = setsockopt(m_hSocket, SOL_SOCKET, SO_RCVTIMEO, (char*)&m_nTimeout, sizeof(m_nTimeout));
  172. if(bread == SOCKET_ERROR)
  173. {
  174. printf("Warning: Setsockopt(SO_RCVTIMEO) failed with status %d", WSAGetLastError());
  175. }
  176. m_usPacketSeqNo = 0;
  177. return 0;
  178. }
  179. void CloseSocket()
  180. {
  181. if(m_hSocket != INVALID_SOCKET)
  182. {
  183. closesocket(m_hSocket);
  184. m_hSocket = INVALID_SOCKET;
  185. }
  186. }
  187. USHORT CheckSum(USHORT* buffer, int nSize)
  188. {
  189. ULONG checkSum = 0;
  190. while(nSize > 1)
  191. {
  192. checkSum += *buffer++;
  193. nSize -= sizeof(USHORT);
  194. }
  195. if(nSize)
  196. {
  197. checkSum += *(UCHAR*)buffer;
  198. }
  199. checkSum = (checkSum >> 16) + (checkSum & 0xffff);
  200. checkSum += (checkSum >> 16);
  201. return (USHORT)(~checkSum);
  202. }
  203. };