我参考网上的内容写了一段实现ping功能的代码,但是在执行时,不论ping什么地址都是显示成功,实在发现不了哪里有问题,求指点迷津。
代码如下:
//全局变量
//icmp header
//This is not the standard header, but we reserve space for time
typedef struct _icmphdr
{
BYTE i_type;
BYTE i_code;
USHORT i_cksum;
USHORT i_id;
USHORT i_seq;
ULONG timestamp;
} IcmpHeader;
//封装的方法
//计算ICMP校验码
USHORT CTransmitDlg::checksum(USHORT* buffer, int size)
{
unsigned long cksum = 0;
while (size > 1)
{
cksum += *buffer++;
size -= sizeof(USHORT);
}
if (size)
{
cksum += *(UCHAR*)buffer;
}
cksum = (cksum>>16) + (cksum & 0xffff);
cksum += (cksum>>16);
return (USHORT)(~cksum);
}
//Ping主函数
int CTransmitDlg::Ping()
{
//WinSocket服务初始化
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2, 1), &wsaData) != 0)
{
AfxMessageBox("WSAStartup() failed:%d\n", GetLastError());
return -1;
}
//变量
char recvbuf[100]; //接受的数据
int timeout = 1000; //超时
struct sockaddr_in from; //发送方结构体
int fromlen = sizeof(from); //发送方结构大小
struct sockaddr_in dest; //接收方
memset(&dest, 0, sizeof(dest)); //接收方清零
CString t_ip; //临时IP存储
CString t_port; //临时端口存储
CString t_msg, t_msgerr; //临时显示信息
long nLength = 0; //显示区信息长度
//创建并设置套接字
SOCKET sockRaw = WSASocket(AF_INET, SOCK_RAW, IPPROTO_ICMP, NULL, 0, WSA_FLAG_OVERLAPPED);
if (sockRaw == INVALID_SOCKET)
{
AfxMessageBox("WSASocket() failed:%d\n", WSAGetLastError());
return -1;
}
setsockopt(sockRaw, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout));
//GetDlgItemText(IDC_IPADDRESS_SERVER, t_ip);
t_ip = "192.168.0.1";
GetDlgItemText(IDC_EDIT_SERVER_PORT, t_port);
dest.sin_family = AF_INET; //Family
dest.sin_addr.s_addr = inet_addr(t_ip); //IP地址
dest.sin_port = (u_short) atoi(t_port); //端口号
//制作ICMP头
char* icmp_data = new char[10];
memset(icmp_data,0,sizeof(icmp_data));
((IcmpHeader*)icmp_data)->i_type = 8; //为8表示回送请求
((IcmpHeader*)icmp_data)->i_code = 0;
((IcmpHeader*)icmp_data)->i_id = (u_short)GetCurrentProcessId(); //获得进程ID作为ICMP的ID号
((IcmpHeader*)icmp_data)->i_seq = 0; //序号
((IcmpHeader*)icmp_data)->i_cksum = 0; //初始化校验码
//开始ping
((IcmpHeader*)icmp_data)->i_cksum = checksum((u_short *)icmp_data, 8);//计算校验码
sendto(sockRaw, icmp_data, 8, 0, (struct sockaddr*)&dest, sizeof(dest));//使用指定的套接字发送字节流数据到指定地址
int bread = recvfrom(sockRaw,recvbuf,100,0,(struct sockaddr*)&from, &fromlen);//接收数据
for(int i = 0; i < PING_TIMES; i++)
{
if (bread == SOCKET_ERROR)
//接收数据失败
{
t_msg.Format("第%d次尝试ping主机%s失败:错误 %ld...\r\n",
i+1,
t_ip,
WSAGetLastError()
);
nLength = m_ctrRichEdit.SendMessage(WM_GETTEXTLENGTH);//追加显示到编辑框里
m_ctrRichEdit.SetSel(nLength,nLength);
m_ctrRichEdit.ReplaceSel(t_msg);
continue;
}
else
//接收数据成功
{
t_msg.Format("第%d次尝试ping主机%s成功,内容:%ld 测试码:%d",
i+1,
t_ip,
recvbuf,
bread
);
nLength = m_ctrRichEdit.SendMessage(WM_GETTEXTLENGTH);//追加显示到编辑框里
m_ctrRichEdit.SetSel(nLength,nLength);
m_ctrRichEdit.ReplaceSel(t_msg);
return 1;
}
}
t_msgerr.Format("连接主机失败,正在尝试重连...");
nLength = m_ctrRichEdit.SendMessage(WM_GETTEXTLENGTH);//追加显示到编辑框里
m_ctrRichEdit.SetSel(nLength,nLength);
m_ctrRichEdit.ReplaceSel(t_msgerr);
return 0;
}
代码如下:
//全局变量
//icmp header
//This is not the standard header, but we reserve space for time
typedef struct _icmphdr
{
BYTE i_type;
BYTE i_code;
USHORT i_cksum;
USHORT i_id;
USHORT i_seq;
ULONG timestamp;
} IcmpHeader;
//封装的方法
//计算ICMP校验码
USHORT CTransmitDlg::checksum(USHORT* buffer, int size)
{
unsigned long cksum = 0;
while (size > 1)
{
cksum += *buffer++;
size -= sizeof(USHORT);
}
if (size)
{
cksum += *(UCHAR*)buffer;
}
cksum = (cksum>>16) + (cksum & 0xffff);
cksum += (cksum>>16);
return (USHORT)(~cksum);
}
//Ping主函数
int CTransmitDlg::Ping()
{
//WinSocket服务初始化
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2, 1), &wsaData) != 0)
{
AfxMessageBox("WSAStartup() failed:%d\n", GetLastError());
return -1;
}
//变量
char recvbuf[100]; //接受的数据
int timeout = 1000; //超时
struct sockaddr_in from; //发送方结构体
int fromlen = sizeof(from); //发送方结构大小
struct sockaddr_in dest; //接收方
memset(&dest, 0, sizeof(dest)); //接收方清零
CString t_ip; //临时IP存储
CString t_port; //临时端口存储
CString t_msg, t_msgerr; //临时显示信息
long nLength = 0; //显示区信息长度
//创建并设置套接字
SOCKET sockRaw = WSASocket(AF_INET, SOCK_RAW, IPPROTO_ICMP, NULL, 0, WSA_FLAG_OVERLAPPED);
if (sockRaw == INVALID_SOCKET)
{
AfxMessageBox("WSASocket() failed:%d\n", WSAGetLastError());
return -1;
}
setsockopt(sockRaw, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout));
//GetDlgItemText(IDC_IPADDRESS_SERVER, t_ip);
t_ip = "192.168.0.1";
GetDlgItemText(IDC_EDIT_SERVER_PORT, t_port);
dest.sin_family = AF_INET; //Family
dest.sin_addr.s_addr = inet_addr(t_ip); //IP地址
dest.sin_port = (u_short) atoi(t_port); //端口号
//制作ICMP头
char* icmp_data = new char[10];
memset(icmp_data,0,sizeof(icmp_data));
((IcmpHeader*)icmp_data)->i_type = 8; //为8表示回送请求
((IcmpHeader*)icmp_data)->i_code = 0;
((IcmpHeader*)icmp_data)->i_id = (u_short)GetCurrentProcessId(); //获得进程ID作为ICMP的ID号
((IcmpHeader*)icmp_data)->i_seq = 0; //序号
((IcmpHeader*)icmp_data)->i_cksum = 0; //初始化校验码
//开始ping
((IcmpHeader*)icmp_data)->i_cksum = checksum((u_short *)icmp_data, 8);//计算校验码
sendto(sockRaw, icmp_data, 8, 0, (struct sockaddr*)&dest, sizeof(dest));//使用指定的套接字发送字节流数据到指定地址
int bread = recvfrom(sockRaw,recvbuf,100,0,(struct sockaddr*)&from, &fromlen);//接收数据
for(int i = 0; i < PING_TIMES; i++)
{
if (bread == SOCKET_ERROR)
//接收数据失败
{
t_msg.Format("第%d次尝试ping主机%s失败:错误 %ld...\r\n",
i+1,
t_ip,
WSAGetLastError()
);
nLength = m_ctrRichEdit.SendMessage(WM_GETTEXTLENGTH);//追加显示到编辑框里
m_ctrRichEdit.SetSel(nLength,nLength);
m_ctrRichEdit.ReplaceSel(t_msg);
continue;
}
else
//接收数据成功
{
t_msg.Format("第%d次尝试ping主机%s成功,内容:%ld 测试码:%d",
i+1,
t_ip,
recvbuf,
bread
);
nLength = m_ctrRichEdit.SendMessage(WM_GETTEXTLENGTH);//追加显示到编辑框里
m_ctrRichEdit.SetSel(nLength,nLength);
m_ctrRichEdit.ReplaceSel(t_msg);
return 1;
}
}
t_msgerr.Format("连接主机失败,正在尝试重连...");
nLength = m_ctrRichEdit.SendMessage(WM_GETTEXTLENGTH);//追加显示到编辑框里
m_ctrRichEdit.SetSel(nLength,nLength);
m_ctrRichEdit.ReplaceSel(t_msgerr);
return 0;
}