请教大家一个问题,我现在急需要一个类似ping操作的mfc函数,只需要给出ip地址根据返回值就可以判断是否是通的就可以了。谢谢!

解决方案 »

  1.   

    http://www.programsalon.com/download.asp?type_id=25
      

  2.   

    有这样的吗??
    我知道用Winsock api可以做到,要不你自己包装一下具体你可以参见Windows网络编程
      

  3.   

    ping操作使用的是ICMP协议,不是TCP/IP协议。
      

  4.   

    ICMP协议应该是IP协议的一部分,而
    不是wzt2000(愚人码头)说的
    不是TCP/IP协议。
      

  5.   

    我现在的这个程序是console程序,只需要一个函数就可以了,那到vc没有封装好的这样的函数吗?只要简单的返回通和不通就可以了。
      

  6.   

    ICMP当然不是IP协议的一部分,只不过ICMP打在IP包中发送罢了
      

  7.   

    to:jennyvenus 非常感谢,请发到,谢谢!你可是帮了我大忙了
      

  8.   

    如下是我从ping程序中摘录的,其中作了一些修改
    typedef struct iphdr {
    unsigned int h_len:4;          // length of the header
    unsigned int version:4;        // Version of IP
    unsigned char tos;             // Type of service
    unsigned short total_len;      // total length of the packet
    unsigned short ident;          // unique identifier
    unsigned short frag_and_flags; // flags
    unsigned char  ttl; 
    unsigned char proto;           // protocol (TCP, UDP etc)
    unsigned short checksum;       // IP checksum unsigned int sourceIP;
    unsigned int destIP;}IpHeader;//
    // ICMP header
    //
    typedef struct _ihdr {
      BYTE i_type;
      BYTE i_code; /* type sub code */
      USHORT i_cksum;
      USHORT i_id;
      USHORT i_seq;
      /* This is not the std header, but we reserve space for time */
      ULONG timestamp;
    }IcmpHeader;int CNet350::ping(LPSTR lpAddr)
    {
      WSADATA wsaData;
      SOCKET sockRaw;
      struct sockaddr_in dest,from;
      struct hostent * hp;
      int bread,datasize;
      int fromlen = sizeof(from);
      int timeout = 1000;
      char *dest_ip;
      char *icmp_data;
      char *recvbuf;
      unsigned int addr=0;
      USHORT seq_no = 0;
      int nRetry;  if (WSAStartup(MAKEWORD(2,1),&wsaData) != 0){
    return SOCKET_INIT_ERROR;
      }
      sockRaw = socket (AF_INET,
       SOCK_RAW,
       IPPROTO_ICMP);  
      if (sockRaw == INVALID_SOCKET) {
    return SOCKET_CREATE_ERROR;
      }
      bread = setsockopt(sockRaw,SOL_SOCKET,SO_RCVTIMEO,(char*)&timeout,
       sizeof(timeout));
      if(bread == SOCKET_ERROR) {
    closesocket(sockRaw);
    return SOCKET_SET_ERROR;
      }
      timeout = 1000;
      bread = setsockopt(sockRaw,SOL_SOCKET,SO_SNDTIMEO,(char*)&timeout,
       sizeof(timeout));
      if(bread == SOCKET_ERROR) {
    closesocket(sockRaw);
    return SOCKET_SET_ERROR;
      }
      memset(&dest,0,sizeof(dest));  hp = gethostbyname(lpAddr);  if (!hp){
    addr = inet_addr(lpAddr);
      }
      if ((!hp)  && (addr == INADDR_NONE) ) {
    closesocket(sockRaw);
    return CANNOT_REACH_IP;
      }  if (hp != NULL)
      memcpy(&(dest.sin_addr),hp->h_addr,hp->h_length);
      else
       dest.sin_addr.s_addr = addr;  if (hp)
      dest.sin_family = hp->h_addrtype;
      else
      dest.sin_family = AF_INET;  dest_ip = inet_ntoa(dest.sin_addr);  datasize = DEF_PACKET_SIZE;

      datasize += sizeof(IcmpHeader);    icmp_data = (char*)xmalloc(MAX_PACKET);
      recvbuf = (char*)xmalloc(MAX_PACKET);  if (!icmp_data) {
    closesocket(sockRaw);
    return CANNOT_REACH_IP;
      }
        memset(icmp_data,0,MAX_PACKET);
      fill_icmp_data(icmp_data,datasize);  for (nRetry = 0; nRetry < 3; nRetry ++) {
    int bwrote;

    ((IcmpHeader*)icmp_data)->i_cksum = 0;
    ((IcmpHeader*)icmp_data)->timestamp = GetTickCount(); ((IcmpHeader*)icmp_data)->i_seq = seq_no++;
    ((IcmpHeader*)icmp_data)->i_cksum = checksum((USHORT*)icmp_data, 
    datasize); bwrote = sendto(sockRaw,icmp_data,datasize,0,(struct sockaddr*)&dest,
    sizeof(dest));
    bread = recvfrom(sockRaw,recvbuf,MAX_PACKET,0,(struct sockaddr*)&from,
     &fromlen);
    if (bread != SOCKET_ERROR && bwrote != SOCKET_ERROR)
    break;
      }
      closesocket(sockRaw);
      if (nRetry < 3)
      return 1;
      else
      return CANNOT_REACH_IP;
    }void CNet350::fill_icmp_data(char *icmp_data, int datasize)
    {
      IcmpHeader *icmp_hdr;
      char *datapart;  icmp_hdr = (IcmpHeader*)icmp_data;  icmp_hdr->i_type = ICMP_ECHO;
      icmp_hdr->i_code = 0;
      icmp_hdr->i_id = (USHORT)GetCurrentProcessId();
      icmp_hdr->i_cksum = 0;
      icmp_hdr->i_seq = 0;
      
      datapart = icmp_data + sizeof(IcmpHeader);
      //
      // Place some junk in the buffer.
      //
      memset(datapart,'E', datasize - sizeof(IcmpHeader));
    }USHORT CNet350::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);
    }
      

  9.   

    to: hustwjz,无论怎样我还是先要感谢你的帮助,
      

  10.   

    http://www.starsoftroom.com/downloads/source_code/Ping.zip
      

  11.   

    呵呵
    我有的也是Console的
    不过有Win32的程序,写的不太好,不好意思给你啦