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);就死了,查了一下好像说是挂起了,应该怎么解决。

解决方案 »

  1.   

    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))//接收到响应答报文信息
    {
    //...
    }
      

  2.   

    设置超时了
    isetsockopt(m_IcmpSock,SOL_SOCKET,SO_RCVTIMEO,(char *)&m_nTimeOut,
    sizeof(m_nTimeOut));//接收超时