2024年6月3日发(作者:)

方法:如何解决用MFC实现的ping功能中把目标主机不可到达的当成ping通的问题

转载请注明来源:/xuesongshu/

网上查到的资料能实现ping功能,但是都有一个问题,它只检测是否存在错误,而不检测ICMP数据包是哪个机器回复的,这样造成一种错误的情况:当PC与路由器连通时,如果路由

器回复该主机不可达,那么程序一样回应PING通了。目前网络上搜索不到相关正确的资料,我把我的方法分享给网友们。

运行截图:

本段程序代码是我做的一个软件的其中的一个功能。该方法是一个线程的主体。

1 UINT DoPingHost(LPVOID lParam)

2 {

3 WSADATA wdPing;

4 SOCKET skPing;

5 DWORD dwIpDest;

6 LARGE_INTEGER liBegin,liEnd,liClockFrequency;

7 double dSpan=0;

8 struct sockaddr_in destAddr,fromAddr;

9 int nTimeOut=3000,nPingCount=4,nBread=0,nFromLen=sizeof(fromAdd

1r),nPingPort=0,nPingFailCount=0,nSliderPos=0;

0 char* cIcmpData=new char[10];

1 char cLoalName[100],cRecvBuffer[100];

1 IcmpHeader* icmpData=(IcmpHeader*)cIcmpData;

1 CLanCopyDlg* cd=(CLanCopyDlg*)lParam;

2 CString szMsg,szTmp;

1 BOOL bCanBrowse=FALSE;

3 ::QueryPerformanceFrequency(&liClockFrequency);

1 memset(cIcmpData,0,sizeof(IcmpHeader));

4 cd->GetDlgItem(IDC_BUTTON_MACHINE)->EnableWindow(FALSE);

1 cd->GetDlgItem(IDC_BUTTON_MACHINE)->SetWindowText("请稍等");

5 if (::WSAStartup(MAKEWORD(2,1),&wdPing))

1 {

6 ::MessageBox(cd->m_hWnd,TEXT("网络初化异常,Socket创建失败!

1"),"异常",MB_OK|MB_ICONERROR);

7 return 0;

1 }

8 skPing=socket(AF_INET,SOCK_RAW,IPPROTO_ICMP);

1 setsockopt(skPing,SOL_SOCKET,SO_RCVTIMEO,(char*)&nTimeOut,sizeo

9 f(nTimeOut));

2 ((CIPAddressCtrl*)(cd->GetDlgItem(IDC_IPADDRESS_DEST)))->GetAdd

0 ress(dwIpDest);

2 dwIpDest=MAKEIPADDRESS(FOURTH_IPADDRESS(dwIpDest),THIRD_IPADDRE

1 SS(dwIpDest),SECOND_IPADDRESS(dwIpDest),FIRST_IPADDRESS(dwIpDest));

2 _addr.S_un.S_addr=dwIpDest;

2 _family=AF_INET;

2 srand(time(NULL));

3 nPingPort=rand()%1024+1024;

2 _port=nPingPort;

4 icmpData->i_type=8;

2 icmpData->i_code=0;

5 icmpData->i_id=(u_short)::GetCurrentProcessId();

2 icmpData->i_seq=0;

6 gethostname(cLoalName,100);

2 nSliderPos=0;

7 cd->m_(nSliderPos);

2 for (int i=0;i

8 {

2 ::QueryPerformanceCounter(&liBegin);

9 icmpData->i_cksum=0;

3 icmpData->i_cksum=in_cksum((u_short*)cIcmpData,8);

0 sendto(skPing,cIcmpData,8,0,(struct sockaddr*)&destAddr,siz

3eof(destAddr));

1 nBread=recvfrom(skPing,cRecvBuffer,100,0,(struct sockaddr*)

3&fromAddr,&nFromLen);