123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382 |
- #include "stdafx2.h"
- #include "TWPing.h"
- #include <sys/types.h>
- CTWPing::CTWPing()
- {
- m_hSocket = INVALID_SOCKET;
- m_bCancelPing = FALSE;
- m_nDataSize = DEFAULT_PACKET_SIZE;
- m_nInterval = DEFAULT_INTERVAL;
- m_nTimeout = DEFAULT_TIMEOUT;
- m_usPacketSeqNo = 0;
- m_icmpData = NULL;
- m_recvBuf = NULL;
- m_bInited = false;
- memset(m_szIP, 0, sizeof(m_szIP));
- }
- CTWPing::~CTWPing(void)
- {
- Cleanup();
- }
- int CTWPing::Initial(const char* destIp, int nDataSize, int nTimeout, int nInterval)
- {
- WSADATA wsaData;
- if(WSAStartup(MAKEWORD(2,2), &wsaData) != 0)
- {
- printf("WSAStartup() failed with status %d", WSAGetLastError());
- return -1;
- }
- strcpy_s(m_szIP, destIp);
- memset(&m_addrDest, 0, sizeof(m_addrDest));
- m_addrDest.sin_family = AF_INET;
- m_addrDest.sin_addr.s_addr = inet_addr(destIp);
- if(m_addrDest.sin_addr.s_addr == INADDR_NONE)
- {
- PHOSTENT hp = NULL;
- struct addrinfo hinst;
- memset(&hinst, 0, sizeof(hinst));
- hinst.ai_family = AF_UNSPEC;
- hinst.ai_socktype = SOCK_STREAM;
- hinst.ai_protocol = IPPROTO_TCP;
-
- struct addrinfo *result = NULL;
- DWORD dwRet = getaddrinfo(destIp, 0, &hinst, &result);
- if(dwRet == 0) {
- struct addrinfo *ptr = NULL;
- for(ptr=result; ptr!=NULL; ptr=ptr->ai_next) {
- m_addrDest.sin_family = ptr->ai_family;
- memcpy(&(m_addrDest.sin_addr), ptr->ai_addr, ptr->ai_addrlen);
- }
- }
- //hp = gethostbyname(destIp);
- //if(hp != NULL)
- //{
- // memcpy(&(m_addrDest.sin_addr), hp->h_addr, hp->h_length);
- // m_addrDest.sin_family = hp->h_addrtype;
- //}
- else
- {
- printf("getaddrinfo() failed with status %d", WSAGetLastError());
- Cleanup();
- return -1;
- }
- }
- m_nDataSize = nDataSize <= 0 ? DEFAULT_PACKET_SIZE : nDataSize;
- m_nInterval = nInterval <= 0 ? DEFAULT_INTERVAL : nInterval;
- m_nTimeout = nTimeout <= 0 ? DEFAULT_TIMEOUT : nTimeout;
- if(InitICMPData() != 0)
- {
- Cleanup();
- return -1;
- }
- if(CreateSocket() != 0)
- {
- Cleanup();
- return -1;
- }
- m_bInited = true;
- return 0;
- }
- int CTWPing::InitICMPData()
- {
- if(m_icmpData == NULL)
- m_icmpData = static_cast<char*>(HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, MAX_PACKET));
- if(m_recvBuf == NULL)
- m_recvBuf = static_cast<char*>(HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, MAX_PACKET));
- if(!m_icmpData || !m_recvBuf)
- {
- printf("HeapAlloc() failed with status %d", WSAGetLastError());
- return -1;
- }
- IcmpHeader* pIcmpHdr = NULL;
- char* dataPart = NULL;
- pIcmpHdr = reinterpret_cast<IcmpHeader*>(m_icmpData);
- pIcmpHdr->btType = ICMP_ECHO;
- pIcmpHdr->btCode = 0;
- pIcmpHdr->usCksum = 0;
- pIcmpHdr->usId = (USHORT)GetCurrentProcessId();
- pIcmpHdr->usSeq = 0;
- dataPart = m_icmpData + sizeof(IcmpHeader);
- memset(dataPart, 0, m_nDataSize);
- return 0;
- }
- int CTWPing::DecodeICMPData(int bytes)
- {
- IpHeader* ipHdr = reinterpret_cast<IpHeader*>(m_recvBuf);
- IcmpHeader* icmpHdr = NULL;
- USHORT ipHdrLen;
- DWORD tickTime = clock();
- if(bytes < DEFAULT_IP_HEAD_SIZE)
- {
- return -1;
- }
- //首部长度字节数,所表示的单位是32位字
- ipHdrLen = ipHdr->h_len * 4;
- if(ipHdrLen < DEFAULT_IP_HEAD_SIZE || ipHdrLen > MAX_IP_HDR_SIZE)
- {
- //识别到长度不能容纳最小ICMP首部长度,无法判断是否为ICMP回应报文
- return -1;
- }
- icmpHdr = reinterpret_cast<IcmpHeader *>(m_recvBuf + ipHdrLen);
- if(icmpHdr->btType != ICMP_ECHO_REPLY)
- {
- //非请求回应报文类型
- return -2;
- }
- if(icmpHdr->usId != (USHORT)GetCurrentProcessId())
- {
- //不是从该程序发出的数据包
- //Dbg("No from here");
- return -2;
- }
- if(icmpHdr->usSeq != GetCurrentSeqNo())
- {
- //接收的数据包序列号错误,一般会很少出现,出现则需要重新设置SOKECT句柄
- //Dbg("SeqNo error");
- return -1;
- }
- if(bytes - ipHdrLen - DEFAULT_ICMP_HEAD_SIZE != m_nDataSize)
- {
- //接收的数据包长度不完整
- return -1;
- }
- return 0;
- }
- int CTWPing::Ping()
- {
- int bread = 0;
- int errResult = 0;
- int result = 0;
- int tryCount = 0;
- const int maxTryCount = 3;
- int timeoutCount = 0;
- const int maxTimeoutCount = 3;
- int errorCount = 0;
- const int maxErrorCount = 3;
- const int aimRecvLen = m_nDataSize + DEFAULT_IP_HEAD_SIZE + DEFAULT_ICMP_HEAD_SIZE;
- const int aimSendLen = m_nDataSize + DEFAULT_ICMP_HEAD_SIZE;
- SOCKADDR_IN addrSource;
- int sourceSize = sizeof(addrSource);
- m_bCancelPing = FALSE;
-
- while(!m_bCancelPing)
- {
- if(m_hSocket == INVALID_SOCKET)
- {
- tryCount = 0;
- while(++tryCount <= maxTryCount)
- {
- if(!CreateSocket())
- break;
- Sleep(1000);
- }
- if(m_hSocket == INVALID_SOCKET)
- {
- printf("create socket beyond %d times", maxTryCount);
- return 1;
- }
- }
- ((IcmpHeader*)m_icmpData)->usCksum = 0;
- ((IcmpHeader*)m_icmpData)->ulTimestamp = clock();
- ((IcmpHeader*)m_icmpData)->usSeq = IncreaseCurSeqNo();
- ((IcmpHeader*)m_icmpData)->usCksum = CheckSum((USHORT*)m_icmpData, aimSendLen);
- bread = sendto(m_hSocket, m_icmpData, aimSendLen, 0,
- (PSOCKADDR)&m_addrDest, sizeof(m_addrDest));
- if(bread == SOCKET_ERROR)
- {
- errResult = WSAGetLastError();
- if(WSAETIMEDOUT == errResult)
- {
- ++timeoutCount;
-
- if(timeoutCount >= maxTimeoutCount)
- {
- printf("Sent ping packet timeout %d times", timeoutCount);
- result = 2;
- break;
- }
- }
- else
- {
- ++errorCount;
-
- if(errorCount >= maxErrorCount)
- {
- printf("Sent ping packet occur error %d", errResult);
- result = 3;
- break;
- }
- }
- CloseSocket();
- Sleep(1000);
- continue;
- }
- if(bread < aimSendLen)
- {
- //CloseSocket();
- //Sleep(1000);
- continue;
- }
- //ReturnToRecv:
- //Recv
- bread = recvfrom(m_hSocket, m_recvBuf, MAX_PACKET, 0, (PSOCKADDR)&addrSource, &sourceSize);
- if(bread == SOCKET_ERROR)
- {
- errResult = WSAGetLastError();
- if(WSAETIMEDOUT == errResult)
- {
- ++timeoutCount;
-
- if(timeoutCount >= maxTimeoutCount)
- {
- printf("Recv ping(%s) packet timeout %d times", m_szIP, timeoutCount);
- result = 2;
- break;
- }
- }
- else
- {
- ++errorCount;
-
- if(errorCount >= maxErrorCount)
- {
- printf("Recv ping(%s) packet occur error %d", m_szIP, errResult);
- result = 3;
- break;
- }
- }
- CloseSocket();
- Sleep(1000);
- continue;
- }
- errorCount = timeoutCount = 0;
- result = DecodeICMPData(bread);
- if(result < 0)
- {
- CloseSocket();
- Sleep(1000);
- continue;
- }
- printf("Ping once");
- Sleep(m_nInterval);
- }
- return result;
- }
- int CTWPing::PingOnce()
- {
- int bread = 0;
- int errResult = 0;
- int result = 0;
- int tryCount = 0;
- const int maxTryCount = 3;
- int revcCount = 0;
- const int maxRevcCount = 3;
- const int aimRecvLen = m_nDataSize + DEFAULT_IP_HEAD_SIZE + DEFAULT_ICMP_HEAD_SIZE;
- const int aimSendLen = m_nDataSize + DEFAULT_ICMP_HEAD_SIZE;
- SOCKADDR_IN addrSource;
- int sourceSize = sizeof(addrSource);
- do
- {
- if(m_hSocket == INVALID_SOCKET)
- {
- CreateSocket();
- result = 1;
- break;
- }
- IcmpHeader* header = reinterpret_cast<IcmpHeader*>(m_icmpData);
- header->usCksum = 0;
- header->ulTimestamp = clock();
- header->usSeq = IncreaseCurSeqNo();
- header->usCksum = CheckSum((USHORT*)m_icmpData, aimSendLen);
- bread = sendto(m_hSocket, m_icmpData, aimSendLen, 0,
- (PSOCKADDR)&m_addrDest, sizeof(m_addrDest));
- if(bread == SOCKET_ERROR)
- {
- errResult = WSAGetLastError();
- if(WSAETIMEDOUT == errResult)
- {
- LOG_TRACE("Sent ping packet timeout");
- result = 2;
- }
- else
- {
- LOG_TRACE("Sent ping packet occur error %d", errResult);
- result = 3;
- }
- break;
- }
- if(bread < aimSendLen)
- {
- LOG_TRACE("Sent ping packet seems incomplete.");
- result = 4;
- break;
- }
- //ReturnToRecv:
- //Recv
- bread = recvfrom(m_hSocket, m_recvBuf, MAX_PACKET, 0, (PSOCKADDR)&addrSource, &sourceSize);
- if(bread == SOCKET_ERROR)
- {
- errResult = WSAGetLastError();
- if(WSAETIMEDOUT == errResult)
- {
- LOG_TRACE("Recv ping(%s) packet timeout", m_szIP);
- result = 2;
- }
- else
- {
- LOG_TRACE("Recv ping(%s) packet occur error %d", m_szIP, errResult);
- result = 3;
- }
- break;
- }
- result = DecodeICMPData(bread);
- if(result < 0)
- {
- CloseSocket();
- result = 4;
- break;
- }
- }while(FALSE);
- return result;
- }
|