标签:packet mod 处理 ping mic HERE text 常用 mtime
Ping功能是测试网络是否连接的有效方式。通常我们需要通过ping来验证网络连接是否正常,这就需要我们经常用到ping功能。
ping是有一定的阻塞,如果频繁使用会导致应用程序出现阻塞现象,为了避免这种情况的发生,我们这里举例用线程的方式对网络进行ping来验证网络是否连接正常:
- UI布局
- 添加按键处理:OnBn1ClickedSendOnBn2ClickedClearOnBn3ClickedReturn
- 添加线程处理:
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;
}
onMyThread1
- 线程向对话框传递消息处理:
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;
}
onPingMessage
- 完整代码:
// myPingDlg.cpp : implementation file
//
#include "stdafx.h"
#include "MicrohardTest.h"
#include "myPingDlg.h"
#include "afxdialogex.h"
//user
#include "MicrohardTestDlg.h"
#include "Source.h"
#include
#include
#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;
}
myPingDlg.cpp
#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;
};
myPingDlg.h
- Ping处理代码:
#include "stdafx.h"
#include "Source.h"
#include
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:" //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;
}
Source.cpp
#pragma once
//在默认windows.h会包含winsock.h,当你包含winsock2.h就会冲突,因此在包含windows.h前需要定义一个宏,#define WIN32_LEAN_AND_MEAN ;去除winsock.h
//要么将#include 放在#include前面或者直接去掉#include
#include #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;
};
Source.h
- 测试:
c++ Ping 通过线程处理Ping功能(MFC)
标签:packet mod 处理 ping mic HERE text 常用 mtime
原文地址:https://www.cnblogs.com/lumao1122-Milolu/p/13140690.html