标签:packet mod 处理 ping mic HERE text 常用 mtime
Ping功能是测试网络是否连接的有效方式。通常我们需要通过ping来验证网络连接是否正常,这就需要我们经常用到ping功能。
ping是有一定的阻塞,如果频繁使用会导致应用程序出现阻塞现象,为了避免这种情况的发生,我们这里举例用线程的方式对网络进行ping来验证网络是否连接正常:
DWORD myPingDlg::onMyThread1(LPVOID lpParameter) { // TODO: Add your control notification handler code here int i; BOOL bResult; CString str; CPing objPing; MyStruct1 *pPingMessage; i = 0; pPingMessage = (MyStruct1*)lpParameter; do { i++; bResult = objPing.Ping(pPingMessage->pDestIP, &pPingMessage->reply, pPingMessage->dwBytes); if (bResult == TRUE) { ::PostMessage(pPingMessage->hwnd, WM_PING, 0, (LPARAM)pPingMessage); } else { ::PostMessage(pPingMessage->hwnd, WM_PING, 1, (LPARAM)i); } Sleep(1000); } while (bEndless); ::PostMessage(pPingMessage->hwnd, WM_PING, 2, NULL); return 0; }
LRESULT myPingDlg::onPingMessage(WPARAM wParam, LPARAM lParam) { UNREFERENCED_PARAMETER(wParam); UNREFERENCED_PARAMETER(lParam); WORD i; CString str,org; MyStruct1 *pMyPingInfo; UpdateData(true); org = m_edit1_ping; i = (WORD)wParam; if (i == 0) { pMyPingInfo = (MyStruct1*)lParam; str.Format(_T("Reply from : bytes=%d time=%ldms TTL=%ld\r\n"), pMyPingInfo->reply.m_dwBytes,pMyPingInfo->reply.m_dwRoundTripTime,pMyPingInfo->reply.m_dwTTL); str.Insert(11, pMyPingInfo->pDestIP); } else if (i == 1) { str.Format(_T("Failed: Ping did not response at %d package.\r\n"), lParam); } else if (i == 2) { str = _T("\r\nPing Test STOP !!!\r\n"); CButton*pbutton = (CButton*)this->GetDlgItem(IDC_BUTTON1); SetDlgItemText(IDC_BUTTON1, _T("PingRetry")); SetDlgItemText(IDC_BUTTON3, _T("Return")); pbutton->EnableWindow(TRUE); CEdit*pEditCtl = (CEdit*)this->GetDlgItem(IDC_EDIT3); pEditCtl->EnableWindow(TRUE); pEditCtl = (CEdit*)this->GetDlgItem(IDC_EDIT4); pEditCtl->EnableWindow(TRUE); } SetDlgItemText(IDC_EDIT1, org+str); CEdit*pCtl = (CEdit*)this->GetDlgItem(IDC_EDIT1); pCtl->LineScroll(pCtl->GetLineCount()); return 0; }
// myPingDlg.cpp : implementation file // #include "stdafx.h" #include "MicrohardTest.h" #include "myPingDlg.h" #include "afxdialogex.h" //user #include "MicrohardTestDlg.h" #include "Source.h" #include <winsock2.h> #include <stdio.h> #include <string.h> // myPingDlg dialog static BOOL bEndless; IMPLEMENT_DYNAMIC(myPingDlg, CDialogEx) myPingDlg::myPingDlg(CWnd* pParent /*=NULL*/) : CDialogEx(myPingDlg::IDD, pParent) , m_edit1_ping(_T("")) , m_edit2_web(_T("192.168.168.1"))/*dw=0xc0a8a801; ping 192.168.168.1 -l 65000 –t*/ , m_dw_edit4_bytes_of_package(32) { } myPingDlg::~myPingDlg() { } void myPingDlg::DoDataExchange(CDataExchange* pDX) { CDialogEx::DoDataExchange(pDX); DDX_Text(pDX, IDC_EDIT1, m_edit1_ping); DDX_Text(pDX, IDC_EDIT3, m_edit2_web); DDX_Text(pDX, IDC_EDIT4, m_dw_edit4_bytes_of_package); DDV_MinMaxUInt(pDX, m_dw_edit4_bytes_of_package, 1, 65000); } BEGIN_MESSAGE_MAP(myPingDlg, CDialogEx) ON_BN_CLICKED(IDC_BUTTON3, &myPingDlg::OnBn3ClickedReturn) ON_BN_CLICKED(IDC_BUTTON1, &myPingDlg::OnBn1ClickedSend) ON_BN_CLICKED(IDC_BUTTON2, &myPingDlg::OnBn2ClickedClear) ON_MESSAGE(WM_PING, onPingMessage) END_MESSAGE_MAP() // myPingDlg message handlers void myPingDlg::OnBn3ClickedReturn() { // TODO: Add your control notification handler code here if (bEndless == TRUE) { bEndless = FALSE; } else { myPingDlg::OnOK(); CMicrohardTestDlg mdlg; mdlg.DoModal(); } } void myPingDlg::OnBn1ClickedSend() { // TODO: Add your control notification handler code here int nCount = 0; char *szDestIP; char szIp0[100][100]; CString str; CPing objPing; char szDomain[256] = { 0 }; //Get ip address from domain UpdateData(true); if (m_dw_edit4_bytes_of_package < 1){ SetDlgItemText(IDC_EDIT4, "1"); return; } else if (m_dw_edit4_bytes_of_package>65000) { SetDlgItemText(IDC_EDIT4,"65000"); return; } GetDlgItem(IDC_EDIT3)->GetWindowText(str); strcpy_s(szDomain, str); BOOL bResult = objPing.GetIpByDomainName(szDomain, szIp0, &nCount); if (bResult == TRUE) { szDestIP = &szIp0[0][0]; DWORD dwIP = ntohl(inet_addr(szDestIP)); CIPAddressCtrl*pIP = (CIPAddressCtrl*)this->GetDlgItem(IDC_IPADDRESS2); pIP->SetAddress(dwIP); if (nCount != 0) { CButton*pbutton = (CButton*)this->GetDlgItem(IDC_BUTTON1); pbutton->EnableWindow(FALSE); SetDlgItemText(IDC_BUTTON1, _T("PingRunning")); SetDlgItemText(IDC_BUTTON3, _T("PingStop")); str.Format(_T("Ping address: with %d bytes of a package:\r\n"), m_dw_edit4_bytes_of_package); str.Insert(13, szDestIP); m_edit1_ping = str; HANDLE hThread; MyStruct1 *pmystruct = new MyStruct1; pmystruct->hwnd = m_hWnd; pmystruct->pDestIP = szDestIP; pmystruct->dwBytes = m_dw_edit4_bytes_of_package; bEndless = TRUE; hThread = CreateThread(NULL, 0, onMyThread1, (LPVOID)pmystruct, 0, NULL); CloseHandle(hThread); CEdit*pEditCtl = (CEdit*)this->GetDlgItem(IDC_EDIT3); pEditCtl->EnableWindow(FALSE); pEditCtl = (CEdit*)this->GetDlgItem(IDC_EDIT4); pEditCtl->EnableWindow(FALSE); } else { m_edit1_ping = _T("Failed! Domain Can‘t Parser !!!"); } } else { m_edit1_ping = _T("WSA Startup failed !!!"); } UpdateData(FALSE); } void myPingDlg::OnBn2ClickedClear() { // TODO: Add your control notification handler code here UpdateData(TRUE); if (m_edit1_ping.IsEmpty()==false) { m_edit1_ping = _T(""); UpdateData(FALSE); } } BOOL myPingDlg::PreTranslateMessage(MSG* pMsg) { if (pMsg->message == WM_KEYDOWN) { switch (pMsg->wParam) { case VK_ESCAPE: { if (bEndless == TRUE) { bEndless = FALSE; } return TRUE; break; } case VK_RETURN: { return TRUE; break; } default: break; } } return CDialog::PreTranslateMessage(pMsg); } DWORD myPingDlg::onMyThread1(LPVOID lpParameter) { // TODO: Add your control notification handler code here int i; BOOL bResult; CString str; CPing objPing; MyStruct1 *pPingMessage; i = 0; pPingMessage = (MyStruct1*)lpParameter; do { i++; bResult = objPing.Ping(pPingMessage->pDestIP, &pPingMessage->reply, pPingMessage->dwBytes); if (bResult == TRUE) { ::PostMessage(pPingMessage->hwnd, WM_PING, 0, (LPARAM)pPingMessage); } else { ::PostMessage(pPingMessage->hwnd, WM_PING, 1, (LPARAM)i); } Sleep(1000); } while (bEndless); ::PostMessage(pPingMessage->hwnd, WM_PING, 2, NULL); return 0; } LRESULT myPingDlg::onPingMessage(WPARAM wParam, LPARAM lParam) { UNREFERENCED_PARAMETER(wParam); UNREFERENCED_PARAMETER(lParam); WORD i; CString str,org; MyStruct1 *pMyPingInfo; UpdateData(true); org = m_edit1_ping; i = (WORD)wParam; if (i == 0) { pMyPingInfo = (MyStruct1*)lParam; str.Format(_T("Reply from : bytes=%d time=%ldms TTL=%ld\r\n"), pMyPingInfo->reply.m_dwBytes,pMyPingInfo->reply.m_dwRoundTripTime,pMyPingInfo->reply.m_dwTTL); str.Insert(11, pMyPingInfo->pDestIP); } else if (i == 1) { str.Format(_T("Failed: Ping did not response at %d package.\r\n"), lParam); } else if (i == 2) { str = _T("\r\nPing Test STOP !!!\r\n"); CButton*pbutton = (CButton*)this->GetDlgItem(IDC_BUTTON1); SetDlgItemText(IDC_BUTTON1, _T("PingRetry")); SetDlgItemText(IDC_BUTTON3, _T("Return")); pbutton->EnableWindow(TRUE); CEdit*pEditCtl = (CEdit*)this->GetDlgItem(IDC_EDIT3); pEditCtl->EnableWindow(TRUE); pEditCtl = (CEdit*)this->GetDlgItem(IDC_EDIT4); pEditCtl->EnableWindow(TRUE); } SetDlgItemText(IDC_EDIT1, org+str); CEdit*pCtl = (CEdit*)this->GetDlgItem(IDC_EDIT1); pCtl->LineScroll(pCtl->GetLineCount()); return 0; }
#pragma once #include "Source.h" // myPingDlg dialog #define WM_PING WM_USER+2 struct MyStruct1 { HWND hwnd; char *pDestIP; PingReply reply; DWORD dwTimeOut; DWORD dwBytes; }; class myPingDlg : public CDialogEx { DECLARE_DYNAMIC(myPingDlg) public: myPingDlg(CWnd* pParent = NULL); // standard constructor virtual ~myPingDlg(); // Dialog Data enum { IDD = IDD_DIALOG2 }; private: static DWORD WINAPI onMyThread1(LPVOID lpParameter); protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support virtual BOOL PreTranslateMessage(MSG* pMsg); afx_msg LRESULT onPingMessage(WPARAM wParam, LPARAM lParam); DECLARE_MESSAGE_MAP() public: CString m_edit1_ping; afx_msg void OnBn3ClickedReturn(); afx_msg void OnBn1ClickedSend(); afx_msg void OnBn2ClickedClear(); CString m_edit2_web; DWORD m_dw_edit4_bytes_of_package; };
#include "stdafx.h" #include "Source.h" #include <iostream> USHORT CPing::s_usPacketSeq = 0; CPing::CPing() :m_szICMPData(NULL), m_bIsInitSucc(FALSE) { WSADATA WSAData; if (WSAStartup(MAKEWORD(1, 1), &WSAData) != 0) { /*如果初始化不成功则报错,GetLastError()返回发生的错误信息*/ printf("WSAStartup() failed: %d\n", GetLastError()); return; } m_event = WSACreateEvent(); m_usCurrentProcID = (USHORT)GetCurrentProcessId(); m_sockRaw = WSASocket(AF_INET, SOCK_RAW, IPPROTO_ICMP, NULL, 0, 0); if (m_sockRaw == INVALID_SOCKET) { std::cerr << "WSASocket() failed:" << WSAGetLastError() << std::endl; //10013 以一种访问权限不允许的方式做了一个访问套接字的尝试。 } else { WSAEventSelect(m_sockRaw, m_event, FD_READ); m_bIsInitSucc = TRUE; m_szICMPData = (char*)malloc(DEF_PACKET_SIZE + sizeof(ICMPHeader)); if (m_szICMPData == NULL) { m_bIsInitSucc = FALSE; } } } CPing::~CPing() { WSACleanup(); if (NULL != m_szICMPData) { free(m_szICMPData); m_szICMPData = NULL; } } BOOL CPing::Ping(DWORD dwDestIP, PingReply *pPingReply,DWORD dwBytes, DWORD dwTimeout) { return PingCore(dwDestIP, pPingReply, dwTimeout, dwBytes); } BOOL CPing::Ping(char *szDestIP, PingReply *pPingReply,DWORD dwBytes, DWORD dwTimeout) { if (NULL != szDestIP) { return PingCore(inet_addr(szDestIP), pPingReply, dwTimeout, dwBytes); } return FALSE; } BOOL CPing::PingCore(DWORD dwDestIP, PingReply *pPingReply, DWORD dwTimeout, DWORD dwBytes) { //判断初始化是否成功 if (!m_bIsInitSucc) { return FALSE; } //配置SOCKET sockaddr_in sockaddrDest; sockaddrDest.sin_family = AF_INET; sockaddrDest.sin_addr.s_addr = dwDestIP; int nSockaddrDestSize = sizeof(sockaddrDest); //构建ICMP包 //int nICMPDataSize = DEF_PACKET_SIZE + sizeof(ICMPHeader); int nICMPDataSize = dwBytes + sizeof(ICMPHeader); ULONG ulSendTimestamp = GetTickCountCalibrate(); USHORT usSeq = ++s_usPacketSeq; memset(m_szICMPData, 0, nICMPDataSize); ICMPHeader *pICMPHeader = (ICMPHeader*)m_szICMPData; pICMPHeader->m_byType = ECHO_REQUEST; pICMPHeader->m_byCode = 0; pICMPHeader->m_usID = m_usCurrentProcID; pICMPHeader->m_usSeq = usSeq; pICMPHeader->m_ulTimeStamp = ulSendTimestamp; pICMPHeader->m_usChecksum = CalCheckSum((USHORT*)m_szICMPData, nICMPDataSize); //发送ICMP报文 if (sendto(m_sockRaw, m_szICMPData, nICMPDataSize, 0, (struct sockaddr*)&sockaddrDest, nSockaddrDestSize) == SOCKET_ERROR) { return FALSE; } //判断是否需要接收相应报文 if (pPingReply == NULL) { return TRUE; } char recvbuf[65536] = { "\0" }; while (TRUE) { //接收响应报文 if (WSAWaitForMultipleEvents(1, &m_event, FALSE, 100, FALSE) != WSA_WAIT_TIMEOUT) { WSANETWORKEVENTS netEvent; WSAEnumNetworkEvents(m_sockRaw, m_event, &netEvent); if (netEvent.lNetworkEvents & FD_READ) { ULONG nRecvTimestamp = GetTickCountCalibrate(); int nPacketSize = recvfrom(m_sockRaw, recvbuf, 65536, 0, (struct sockaddr*)&sockaddrDest, &nSockaddrDestSize); if (nPacketSize != SOCKET_ERROR) { IPHeader *pIPHeader = (IPHeader*)recvbuf; USHORT usIPHeaderLen = (USHORT)((pIPHeader->m_byVerHLen & 0x0f) * 4); ICMPHeader *pICMPHeader = (ICMPHeader*)(recvbuf + usIPHeaderLen); if (pICMPHeader->m_usID == m_usCurrentProcID //是当前进程发出的报文 && pICMPHeader->m_byType == ECHO_REPLY //是ICMP响应报文 && pICMPHeader->m_usSeq == usSeq //是本次请求报文的响应报文 ) { pPingReply->m_usSeq = usSeq; pPingReply->m_dwRoundTripTime = nRecvTimestamp - pICMPHeader->m_ulTimeStamp; pPingReply->m_dwBytes = nPacketSize - usIPHeaderLen - sizeof(ICMPHeader); pPingReply->m_dwTTL = pIPHeader->m_byTTL; return TRUE; } } } } //超时 if (GetTickCountCalibrate() - ulSendTimestamp >= dwTimeout) { return FALSE; } } } USHORT CPing::CalCheckSum(USHORT *pBuffer, int nSize) { unsigned long ulCheckSum = 0; while (nSize > 1) { ulCheckSum += *pBuffer++; nSize -= sizeof(USHORT); } if (nSize) { ulCheckSum += *(UCHAR*)pBuffer; } ulCheckSum = (ulCheckSum >> 16) + (ulCheckSum & 0xffff); ulCheckSum += (ulCheckSum >> 16); return (USHORT)(~ulCheckSum); } ULONG CPing::GetTickCountCalibrate() { static ULONG s_ulFirstCallTick = 0; static LONGLONG s_ullFirstCallTickMS = 0; SYSTEMTIME systemtime; FILETIME filetime; GetLocalTime(&systemtime); SystemTimeToFileTime(&systemtime, &filetime); LARGE_INTEGER liCurrentTime; liCurrentTime.HighPart = filetime.dwHighDateTime; liCurrentTime.LowPart = filetime.dwLowDateTime; LONGLONG llCurrentTimeMS = liCurrentTime.QuadPart / 10000; if (s_ulFirstCallTick == 0) { s_ulFirstCallTick = GetTickCount(); } if (s_ullFirstCallTickMS == 0) { s_ullFirstCallTickMS = llCurrentTimeMS; } return s_ulFirstCallTick + (ULONG)(llCurrentTimeMS - s_ullFirstCallTickMS); } BOOL CPing::GetIpByDomainName(char *szHost, char szIp[100][100], int *nCount) { WSADATA wsaData; HOSTENT *pHostEnt; int nAdapter = 0; struct sockaddr_in sAddr; if (WSAStartup(0x0101, &wsaData)) { return FALSE; } pHostEnt = gethostbyname(szHost); if (pHostEnt) { while (pHostEnt->h_addr_list[nAdapter]) { memcpy(&sAddr.sin_addr.s_addr, pHostEnt->h_addr_list[nAdapter], pHostEnt->h_length); char szBuffer[1024] = { 0 }; sprintf_s(szBuffer, "%s", inet_ntoa(sAddr.sin_addr)); strcpy_s(szIp[nAdapter], szBuffer); nAdapter++; } *nCount = nAdapter; } else { *nCount = 0; } WSACleanup(); return TRUE; }
#pragma once //在默认windows.h会包含winsock.h,当你包含winsock2.h就会冲突,因此在包含windows.h前需要定义一个宏,#define WIN32_LEAN_AND_MEAN ;去除winsock.h //要么将#include <winsock2.h>放在#include<windows.h>前面或者直接去掉#include<windows.h> #include <winsock2.h> #pragma comment(lib, "WS2_32") // 链接到WS2_32.lib #define DEF_PACKET_SIZE 65000 #define ECHO_REQUEST 8 #define ECHO_REPLY 0 struct IPHeader { BYTE m_byVerHLen; //4位版本+4位首部长度 BYTE m_byTOS; //服务类型 USHORT m_usTotalLen; //总长度 USHORT m_usID; //标识 USHORT m_usFlagFragOffset; //3位标志+13位片偏移 BYTE m_byTTL; //TTL BYTE m_byProtocol; //协议 USHORT m_usHChecksum; //首部检验和 ULONG m_ulSrcIP; //源IP地址 ULONG m_ulDestIP; //目的IP地址 }; struct ICMPHeader { BYTE m_byType; //类型 BYTE m_byCode; //代码 USHORT m_usChecksum; //检验和 USHORT m_usID; //标识符 USHORT m_usSeq; //序号 ULONG m_ulTimeStamp; //时间戳(非标准ICMP头部) }; struct PingReply { USHORT m_usSeq; DWORD m_dwRoundTripTime; DWORD m_dwBytes; DWORD m_dwTTL; }; class CPing { public: CPing(); ~CPing(); BOOL Ping(DWORD dwDestIP, PingReply *pPingReply = NULL, DWORD dwBytes = 32, DWORD dwTimeout = 2000); BOOL Ping(char *szDestIP, PingReply *pPingReply = NULL, DWORD dwBytes = 32, DWORD dwTimeout = 2000); BOOL GetIpByDomainName(char *szHost, char szIp[100][100], int *nCount); private: BOOL PingCore(DWORD dwDestIP, PingReply *pPingReply, DWORD dwTimeout, DWORD dwBytes); USHORT CalCheckSum(USHORT *pBuffer, int nSize); ULONG GetTickCountCalibrate(); private: SOCKET m_sockRaw; WSAEVENT m_event; USHORT m_usCurrentProcID; char *m_szICMPData; BOOL m_bIsInitSucc; private: static USHORT s_usPacketSeq; };
标签:packet mod 处理 ping mic HERE text 常用 mtime
原文地址:https://www.cnblogs.com/lumao1122-Milolu/p/13140690.html