#include"Init_ping.h"
#include <iostream>
#define DEF_PACKET_SIZE 32
#define ECHO_REQUEST 8
#define ECHO_REPLY 0
USHORT CPing::s_usPacketSeq = 0;
USHORT CPing::Cchecksum(USHORT *buffer,int len)//检验和算法:16位字二进制反码相加的反码
{
unsigned long cksum=0;
while(len>1)
{
cksum+= *buffer++;
len -=sizeof(USHORT);
}
if(len)
{
cksum += *(UCHAR*)buffer;
}
cksum=(cksum>>16)+(cksum&0xffff);
cksum +=(cksum>>16);
return (USHORT)(~cksum);
}
CPing::CPing() :szICMPData(NULL),bIsInitSucc(FALSE) //函数创建
{
WSADATA WSAData; //保存WSAStartup返回的SOCKET
//WSAStartup(MAKEWORD(2, 2), &WSAData);
if (WSAStartup(MAKEWORD(1, 1), &WSAData) != 0)
{
/*如果初始化不成功则报错,GetLastError()返回发生的错误信息*/
printf("WSAStartup() failed: %d\n", GetLastError());
return;
}
Event = WSACreateEvent(); //创建一个新对象
usCurrentProcID = (USHORT)GetCurrentProcessId(); //获取当前进程一个唯一的标识符
//setsockopt(m_sockRaw);
/*if ((m_sockRaw = WSASocket(AF_INET, SOCK_RAW, IPPROTO_ICMP, NULL, 0, 0)) != SOCKET_ERROR)
{
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;
}
}*/
soce = WSASocket(AF_INET, SOCK_RAW, IPPROTO_ICMP, NULL, 0, 0); //创建一个原始套接字
if (soce == INVALID_SOCKET)
{
std::cerr << "WSASocket() failed:" << WSAGetLastError ()<< std::endl; //10013 以一种访问权限不允许的方式做了一个访问套接字的尝试。
}
else
{
WSAEventSelect(soce, Event, FD_READ);
bIsInitSucc = TRUE;
szICMPData = (char*)malloc(DEF_PACKET_SIZE + sizeof(IcmpHeader));
if (szICMPData == NULL)
{
bIsInitSucc = FALSE;
}
}
}
CPing::~CPing() //析构函数
{
WSACleanup();
if (NULL != szICMPData)
{
free(szICMPData);
szICMPData = NULL;
}
}
BOOL CPing::Ping(DWORD wdestIP, PingReply *pPingReply, DWORD wTimeout)
{
return PingCore(wdestIP, pPingReply, wTimeout);
}
BOOL CPing::Ping(char *szdestIP, PingReply *pPingReply, DWORD dwTimeout)
{
if (NULL != szdestIP)
{
return PingCore(inet_addr(szdestIP), pPingReply, dwTimeout); //IP转换
}
return FALSE;
}
BOOL CPing::PingCore(DWORD wdestIP, PingReply *pPingReply, DWORD wTimeout)
{
//判断初始化是否成功
if (!bIsInitSucc)
{
return FALSE;
}
//配置SOCKET
sockaddr_in sockaddrDest;
sockaddrDest.sin_family = AF_INET;
sockaddrDest.sin_addr.s_addr = wdestIP;
int nSockaddrDestSize = sizeof(sockaddrDest);
PINGping pping;
//构建ICMP包
int nICMPDataSize = DEF_PACKET_SIZE + sizeof(IcmpHeader);
ULONG ulSendTimestamp = GetTickCountCalibrate();
USHORT usSeq = ++s_usPacketSeq;
memset(szICMPData, 0, nICMPDataSize);
IcmpHeader *pIcmpHeader=(IcmpHeader*)szICMPData;
pIcmpHeader->IcmpType = ECHO_REQUEST;
pIcmpHeader->IcmpCode = 0;
pIcmpHeader->IcmpId = usCurrentProcID;
pIcmpHeader->IcmpSeq = usSeq;
pIcmpHeader->IcmpTimestamp = ulSendTimestamp;
pIcmpHeader->IcmpChecksum = Cchecksum((USHORT*)szICMPData, nICMPDataSize);
//发送ICMP报文
if (sendto(soce, szICMPData, nICMPDataSize, 0, (struct sockaddr*)&sockaddrDest, nSockaddrDestSize) == SOCKET_ERROR)
{
return FALSE;
}
//判断是否需要接收相应报文
if (pPingReply == NULL)
{
return TRUE;
}
char recvbuf[256] = { "\0" };
while (TRUE)
{
//接收响应报文
if (WSAWaitForMultipleEvents(1, &Event, FALSE, 100, FALSE) != WSA_WAIT_TIMEOUT)
{
WSANETWORKEVENTS netEvent;
WSAEnumNetworkEvents(soce, Event, &netEvent);
if (netEvent.lNetworkEvents & FD_READ)
{
ULONG nRecvTimestamp = GetTickCountCalibrate();
int nPacketSize = recvfrom(soce, recvbuf, 256, 0, (struct sockaddr*)&sockaddrDest, &nSockaddrDestSize);
if (nPacketSize != SOCKET_ERROR)
{
IpHeader *pIPHeader = (IpHeader*)recvbuf;
USHORT usIPHeaderLen = (USHORT)((pIPHeader->Version_and_HeaderLength & 0x0f) * 4);
IcmpHeader *pICMPHeader = (IcmpHeader*)(recvbuf + usIPHeaderLen);
if (pICMPHeader->IcmpId == usCurrentProcID //是当前进程发出的报文
&& pICMPHeader->IcmpType == ECHO_REPLY //是ICMP响应报文
&& pICMPHeader->IcmpSeq == usSeq //是本次请求报文的响应报文
)
{
pPingReply->IcmpSeq = usSeq;
pPingReply->RoundTripTime = nRecvTimestamp - pICMPHeader->IcmpTimestamp;
pPingReply->Bytes = nPacketSize - usIPHeaderLen - sizeof(IcmpHeader);
pPingReply->TTL = pIPHeader->TTL;
return TRUE;
}
}
}
}
//超时
if ((GetTickCountCalibrate() - ulSendTimestamp) >= wTimeout)
{
return FALSE;
}
}
}
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);
}
没有合适的资源?快使用搜索试试~ 我知道了~
PING程序设计测试网络连通
共83个文件
tlog:64个
obj:4个
cpp:2个
需积分: 3 13 下载量 171 浏览量
2016-12-31
11:04:00
上传
评论 2
收藏 7.66MB RAR 举报
温馨提示
PING程序是我们使用的比较多的用于测试网络连通性的程序。PING程序基于ICMP,使用ICMP的回送请求和回送应答来工作。由计算机网络课程知道,ICMP是基于IP的一个协议,ICMP包通过IP的封装之后传递。 课程设计中选取PING程序的设计,其目的是希望同学们通过PING程序的设计,能初步掌握TCP/IP网络协议的基本实现方法,对网络的实现机制有进一步的认识。
资源推荐
资源详情
资源评论
收起资源包目录
ConsoleApplication1.rar (83个子文件)
ConsoleApplication1
ConsoleApplication1
Init_ping.h 2KB
Init_ping.cpp 6KB
ConsoleApplication1.vcxproj 4KB
main.cpp 2KB
Debug
vc110.idb 947KB
link.7048-rc.write.1.tlog 2B
link.8572-cvtres.write.1.tlog 2B
CL.write.1.tlog 7KB
Reply_and_recives.obj 174KB
CL.read.1.tlog 90KB
link.6908.read.1.tlog 2B
link.8900-rc.read.1.tlog 2B
link.1228-rc.write.1.tlog 2B
link.1228.write.1.tlog 2B
link.1228.read.1.tlog 2B
link.8600-rc.read.1.tlog 2B
link.5336-cvtres.write.1.tlog 2B
link.8900-cvtres.write.1.tlog 2B
link.5336.write.1.tlog 2B
link.4104-rc.read.1.tlog 2B
link.8600.write.1.tlog 2B
link.8900-cvtres.read.1.tlog 2B
link.3016-cvtres.write.1.tlog 2B
link.7048.read.1.tlog 2B
link.8900.read.1.tlog 2B
link.4104-cvtres.write.1.tlog 2B
Init_ping.obj 174KB
cl.command.1.tlog 3KB
link-cvtres.read.1.tlog 2B
link.8572.read.1.tlog 2B
link.1228-cvtres.write.1.tlog 2B
link.6908-cvtres.read.1.tlog 2B
link.8900.write.1.tlog 2B
link.6908.write.1.tlog 2B
main.obj 174KB
link.5336-rc.read.1.tlog 2B
link.5336-rc.write.1.tlog 2B
link.7048-cvtres.read.1.tlog 2B
link.6908-rc.read.1.tlog 2B
link.1228-rc.read.1.tlog 2B
link.3016-cvtres.read.1.tlog 2B
link.write.1.tlog 1KB
link.7048-cvtres.write.1.tlog 2B
link.6908-cvtres.write.1.tlog 2B
Init.obj 149KB
link-rc.write.1.tlog 2B
link.5336-cvtres.read.1.tlog 2B
link.8600-cvtres.read.1.tlog 2B
link-cvtres.write.1.tlog 2B
link.1228-cvtres.read.1.tlog 2B
link.4104.write.1.tlog 2B
link.command.1.tlog 3KB
link.7048.write.1.tlog 2B
link-rc.read.1.tlog 2B
link.8600-rc.write.1.tlog 2B
link.read.1.tlog 3KB
link.4104-rc.write.1.tlog 2B
vc110.pdb 428KB
link.8600-cvtres.write.1.tlog 2B
link.8572-rc.write.1.tlog 2B
link.8572-rc.read.1.tlog 2B
link.4104.read.1.tlog 2B
link.3016.write.1.tlog 2B
link.8572.write.1.tlog 2B
ConsoleApplication1.log 2KB
link.7048-rc.read.1.tlog 2B
link.6908-rc.write.1.tlog 2B
link.8600.read.1.tlog 2B
link.8572-cvtres.read.1.tlog 2B
link.8900-rc.write.1.tlog 2B
link.4104-cvtres.read.1.tlog 2B
link.3016.read.1.tlog 2B
link.3016-rc.read.1.tlog 2B
link.3016-rc.write.1.tlog 2B
ConsoleApplication1.lastbuildstate 114B
link.5336.read.1.tlog 2B
ConsoleApplication1.vcxproj.filters 1KB
ConsoleApplication1.sdf 33.38MB
ConsoleApplication1.sln 924B
Debug
ConsoleApplication1.exe 72KB
ConsoleApplication1.pdb 1.03MB
ConsoleApplication1.ilk 1.59MB
ConsoleApplication1.v11.suo 33KB
共 83 条
- 1
资源评论
我不冻
- 粉丝: 7
- 资源: 9
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功