bool CPing::onPing(CString strHost)
{
SOCKET hSocket;
sockaddr_in ipDest;
sockaddr_in addrFrom; char *icmpData; //指向发送ICMP报文的数据缓冲区
char *icmpRecvBuf; // TODO: Add your control notification handler code here
hSocket = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
if (hSocket == INVALID_SOCKET) //创建一个底层套接字
{
return (false);
} //发送前,对IP报文数据区内容进行填写
int size = DEF_PACKET_SIZE + ICMP_MIN;
icmpData = new char[size];
memset(icmpData, 0, size);
ICMPHEADER* icmpHeader = NULL;
icmpHeader = (ICMPHEADER*) icmpData;
icmpHeader->icmpType = ICMP_ECHO;
icmpHeader->icmpCode = 0;
icmpHeader->icmpId = (USHORT) GetCurrentProcessId(); //本进程的ID值
icmpHeader->icmpTimeStamp = GetCurrentTime();
char *datapart = icmpData + sizeof(ICMPHEADER); //指向数据区
memset(datapart, 'E', size-sizeof(ICMPHEADER)); //用E填充数据区 icmpHeader->icmpCheckSum = CheckSum(icmpData, size); //填充校验和,CheckSum函数完成校验和的计算
//发送ICMP报文
if (!GetIPAddr(strHost, ipDest)) //获取IP地址
{
return (false);
}
int result;
result = sendto(hSocket, icmpData, size, 0, (SOCKADDR*) &ipDest, sizeof(ipDest));
if(result == SOCKET_ERROR)
{
return (false);
}
//接收回响应答报文
int RecvLen = sizeof(addrFrom);
icmpRecvBuf = new char[MAX_PACKET];
result = recvfrom(hSocket, icmpRecvBuf, MAX_PACKET, 0, (SOCKADDR*) &addrFrom, &RecvLen);
if (result == SOCKET_ERROR)
{
return (false);
}
// SetFree
if(hSocket != INVALID_SOCKET)
{
closesocket(hSocket);
hSocket = INVALID_SOCKET;
}
if(icmpData != NULL)
{
delete icmpData;
icmpData = NULL;
}
if(icmpRecvBuf!=NULL)
{
delete icmpRecvBuf;
icmpRecvBuf = NULL;
} return (true);
}
==========
上面是实现PING的一段源码,问题是如果PING一个PING不通的地址,程序执行到result = recvfrom(hSocket, icmpRecvBuf, MAX_PACKET, 0, (SOCKADDR*) &addrFrom, &RecvLen);就死了,查了一下好像说是挂起了,应该怎么解决。
{
SOCKET hSocket;
sockaddr_in ipDest;
sockaddr_in addrFrom; char *icmpData; //指向发送ICMP报文的数据缓冲区
char *icmpRecvBuf; // TODO: Add your control notification handler code here
hSocket = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
if (hSocket == INVALID_SOCKET) //创建一个底层套接字
{
return (false);
} //发送前,对IP报文数据区内容进行填写
int size = DEF_PACKET_SIZE + ICMP_MIN;
icmpData = new char[size];
memset(icmpData, 0, size);
ICMPHEADER* icmpHeader = NULL;
icmpHeader = (ICMPHEADER*) icmpData;
icmpHeader->icmpType = ICMP_ECHO;
icmpHeader->icmpCode = 0;
icmpHeader->icmpId = (USHORT) GetCurrentProcessId(); //本进程的ID值
icmpHeader->icmpTimeStamp = GetCurrentTime();
char *datapart = icmpData + sizeof(ICMPHEADER); //指向数据区
memset(datapart, 'E', size-sizeof(ICMPHEADER)); //用E填充数据区 icmpHeader->icmpCheckSum = CheckSum(icmpData, size); //填充校验和,CheckSum函数完成校验和的计算
//发送ICMP报文
if (!GetIPAddr(strHost, ipDest)) //获取IP地址
{
return (false);
}
int result;
result = sendto(hSocket, icmpData, size, 0, (SOCKADDR*) &ipDest, sizeof(ipDest));
if(result == SOCKET_ERROR)
{
return (false);
}
//接收回响应答报文
int RecvLen = sizeof(addrFrom);
icmpRecvBuf = new char[MAX_PACKET];
result = recvfrom(hSocket, icmpRecvBuf, MAX_PACKET, 0, (SOCKADDR*) &addrFrom, &RecvLen);
if (result == SOCKET_ERROR)
{
return (false);
}
// SetFree
if(hSocket != INVALID_SOCKET)
{
closesocket(hSocket);
hSocket = INVALID_SOCKET;
}
if(icmpData != NULL)
{
delete icmpData;
icmpData = NULL;
}
if(icmpRecvBuf!=NULL)
{
delete icmpRecvBuf;
icmpRecvBuf = NULL;
} return (true);
}
==========
上面是实现PING的一段源码,问题是如果PING一个PING不通的地址,程序执行到result = recvfrom(hSocket, icmpRecvBuf, MAX_PACKET, 0, (SOCKADDR*) &addrFrom, &RecvLen);就死了,查了一下好像说是挂起了,应该怎么解决。
if (result == SOCKET_ERROR)
{
return (false);
}
改为:
if(!recvfrom(hSocket, icmpRecvBuf, MAX_PACKET, 0, (SOCKADDR*) &addrFrom, &RecvLen))//接收到响应答报文信息
{
//...
}
isetsockopt(m_IcmpSock,SOL_SOCKET,SO_RCVTIMEO,(char *)&m_nTimeOut,
sizeof(m_nTimeOut));//接收超时