VC++控制台下ping功能的代码

http://read.pudn.com/downloads80/sourcecode/windows/network/307147/Ping/Ping.cpp__.htm

// #pragma pack(4)    
// #pragma comment(lib, "ws2_32.lib")  
// #include "stdafx.h" 
// #include <winsock2.h>   
// #include <stdlib.h>   
// #include <stdio.h>   
//    
// //IP报文报头结构   
// typedef struct ipheader                
// {   
//     unsigned int headlen:4;         //长度   
//     unsigned int version:4;         //版本   
//     unsigned char tos;              //服务类型   
//     unsigned short totallen;        //IP包总长度   
//     unsigned short idflag;          //标识   
//     unsigned short flag;            //标志(前3位)   
//     unsigned char ttl;              //生命期   
//     unsigned char prot;             //协议   
//     unsigned short checksum;        //报头校验和   
//     unsigned int sourceIP;          //源地址   
//     unsigned int destIP;            //目标地址   
// }IpHeader;   
//    
// //ICMP报文报头   
// typedef struct icmpheader{   
//     BYTE type;                      //ICMP类型码,回送请求的类型码为8   
//     BYTE code;                      // 子类型码,保存与特ICMP报文类型相关的细节位置   
//     USHORT checksum;                //校验和   
//     USHORT id;                      //ICMP报文ID号(一般用进程号作为ID)   
//     USHORT seq;                     //ICMP数据报的序列号   
//     ULONG timestamp;   
// }IcmpHeader;   
//    
// #define ICMP_ECHO 8                                 //请求回送   
// #define ICMP_ECHOREPLY 0                            //请求回应   
// #define ICMP_MIN 8                                  //ICMP包头长度(最小ICMP包长度)   
//    
// #define DEF_PACKET_NUMBER  4                        // 发送数据报的个数   
// #define STATUS_FAILED 0xFFFF                        //错误码   
//    
// #define DEF_PACKET_SIZE 32                          //缺省数据报的长度   
// #define MAX_PACKET 1024                             //最大数据报长度   
// #define xmalloc(s) HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,(s))    
// #define xfree(p) HeapFree (GetProcessHeap(),0,(p))    
//    
// void fill_icmp_data(char *, int);                   //填充ICMP包   
// USHORT checksum(USHORT *, int);                     //校验和函数   
// int decode_resp(char *,int ,struct sockaddr_in *);  //找到此数据报IP地址   
//    
// int main(int argc,char **argv)   
// {   
//     WSADATA wsaData;   
//     SOCKET sockRaw;                                 //原始套接字   
//     struct sockaddr_in dest,from;                   //dest:搜索目的IP;from:接收ICMP包的IP   
//     struct hostent *hp;                             //设置本地IP地址   
//     int bread,datasize,times;      
//    
//     int fromlen = sizeof(from);                     //接收ICMP包长度   
//     unsigned int addr = 0;                          //IP地址   
//     int timeout = 1000;                             //设置读取延时   
//     char *dest_ip;   
//     char *icmp_data;                                //设置ICMP数据报最大可能的长度   
//     char *recvbuf;                                  //接收ICMP包缓冲区   
//     USHORT seq_no = 0;   
//     int statistic = 0;   
//     int i;   
//    
//     if(argc < 2)                                 //判断输入格式是否正确   
//     {   
//         printf("输入格式错误: hping hostname\n");   
//         ExitProcess(STATUS_FAILED);   
//     }   
//    
//     if(WSAStartup(MAKEWORD(2,1), &wsaData) != 0)    //开始使用ws2_32.dll   
//     {   
//         printf("WSAStartup failed: %d\n",GetLastError());   
//         ExitProcess(STATUS_FAILED);   
//     }   
//    
//     /**************************  
//     *创建原始套接字,使用WSASocket()函数  
//     *参数1:指定通信发生的区字段,AF_INET允许在远程主机之间通信  
//     *参数2:在AF_INET地址族下,有SOCK_STREAM,SOCK_DGRAM,SOCK_RAW三种套接字,这里表明使用原始套接字  
//     *参数3:依赖参数2,用于指定套接字所用的特定协议,这里使用ICMP协议  
//     *参数4:为WSAPROTOCOL_INFO位,可以置空  
//     *参数5:恒为0  
//     *参数6:标志位,为WSA_FLAG_OVERLAPPED时表明可以使用发送接收超时设置,为0时不考虑  
//     **************************/   
//     sockRaw = WSASocket(AF_INET,SOCK_RAW,IPPROTO_ICMP,NULL,0,WSA_FLAG_OVERLAPPED);   
//     if(sockRaw == INVALID_SOCKET)   
//     {   
//         printf("WSASocket() Failed: %d",WSAGetLastError());   
//         ExitProcess(STATUS_FAILED);   
//     }   
//    
//     /***************************************  
//     *函数名:setsocket  
//     *参数:1:设置原始套接字  
//     *      2:设置使用协议(TCP,UDP, ect)  
//     *      3:SO_SOCKET 表示使用接收超时设置,SO_SNDTIMEO表示使用发送超时设置  
//     ****************************************/   
//     bread = setsockopt(sockRaw,SOL_SOCKET,SO_RCVTIMEO,(char*)&timeout,sizeof(timeout));   
//     if(bread == SOCKET_ERROR)   
//     {   
//         printf("failed to set recv timeout: %d",WSAGetLastError());   
//         ExitProcess(STATUS_FAILED);   
//     }   
//    
//     timeout = 1000;   
//     bread = setsockopt(sockRaw,SOL_SOCKET,SO_SNDTIMEO,(char*)&timeout,sizeof(timeout));   
//     if(bread == SOCKET_ERROR)   
//     {   
//         printf("failed to set send timeout: %d",WSAGetLastError());   
//         ExitProcess(STATUS_FAILED);   
//     }   
//    
//     /***********************  
//     *函数名:memset  
//     *功能  :当程序使用数组和指向内存区域的指针的时候,在一段内存块中填充某个给定的值  
//     *注意  :第二个参数必须为0  
//     ***********************/   
//     memset(&dest,0,sizeof(dest));                       //初始化dest结构   
//    
//     if(argv[1][0] == '/'){   
//         hp = gethostbyname(argv[2]);                    //获得主机名   
//         if(!hp)        
//         {   
//             addr = inet_addr(argv[2]);                  //将一个点间隔地址转换成一个in_addr   
//         }   
//         if((!hp) && (addr == INADDR_NONE))   
//         {   
//             printf("Do not mark address: %s\n",argv[2]);   
//             ExitProcess(STATUS_FAILED);   
//         }   
//     }else{   
//         hp = gethostbyname(argv[1]);                        //获得主机名   
//         if(!hp)    
//         {   
//             addr = inet_addr(argv[1]);                      //将一个点间隔地址转换成一个in_addr   
//         }   
//         if((!hp) && (addr == INADDR_NONE))   
//         {   
//             printf("Do not mark address: %s\n",argv[1]);   
//             ExitProcess(STATUS_FAILED);   
//         }   
//     }   
//     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);                 //将网络地址转换成“.”点隔的字符串格式   
//    
//    
//     /*******************************  
//     *  atoi函数原型是: int atoi( const char *string );  
//     *  如果输出不能确定为int类型,则返回0  
//     *******************************/   
//     if(argc > 2)   
//     {   
//         times = atoi(argv[2]);   
//         if(times == 0)   
//             times = DEF_PACKET_NUMBER;                  //设置ICMP数据报报文体的缺省长度   
//     }else times = DEF_PACKET_NUMBER;   
//    
//     if(argc > 3)   
//     {   
//         datasize = atoi(argv[3]);   
//         if(datasize == 0)   
//             datasize = DEF_PACKET_SIZE;                 //设置ICMP数据报报文体的缺省长度   
//         if(datasize > 1024)                              //数据包太大   
//         {   
//             printf("Warning: data_size is too long.\n");   
//             datasize = DEF_PACKET_SIZE;   
//         }   
//     }else datasize = DEF_PACKET_SIZE;   
//    
//     datasize += sizeof(IcmpHeader);                     //加上ICMP头部的长度   
//     icmp_data = (char*)xmalloc(MAX_PACKET);   
//     recvbuf = (char*)xmalloc(MAX_PACKET);   
//     if(!icmp_data)   
//     {   
//         printf("HeapAlloc failed %d\n",GetLastError());   
//         ExitProcess(STATUS_FAILED);   
//     }   
//    
//     memset(icmp_data,0,MAX_PACKET);                     //将数据报清空初始化   
//     fill_icmp_data(icmp_data,datasize);                 //填充ICMP数据报   
//    
//     //显示提示信息   
//     printf("\nPinging %s .....\n\n",dest_ip);   
//    
//     for(i=0;i<times;i++)   
//     {   
//         int bwrote;   
//         if(argv[1][0] == '/'){                          //处理 /t 参数   
//             if(argv[1][1] == 't')   
//                 i=0;   
//             else{   
//                 printf("参数错误!\n");   
//                 return 1;   
//             }   
//         }   
//         ((IcmpHeader*)icmp_data)->checksum = 0;          //先将校验和置0   
//         ((IcmpHeader*)icmp_data)->timestamp = GetTickCount();   
//         ((IcmpHeader*)icmp_data)->seq = seq_no++;   
//    
//         //计算校验和后填入   
//         ((IcmpHeader*)icmp_data)->checksum = checksum((USHORT*)icmp_data,datasize);   
//         //发送数据报   
//         bwrote = sendto(sockRaw,icmp_data,datasize,0,(struct sockaddr*)&dest,sizeof(dest));   
//         if(bwrote == SOCKET_ERROR)   
//         {   
//             if(WSAGetLastError() == WSAETIMEDOUT)   
//             {   
//                 printf("REQUEST time out\n");   
//                 continue;   
//             }   
//             printf("sendto failed: %d\n",WSAGetLastError());   
//             ExitProcess(STATUS_FAILED);   
//         }   
//         if(bwrote < datasize)   
//         {   
//             printf("Wrote %d bytes\n",bwrote);   
//             ExitProcess(STATUS_FAILED);   
//         }   
//         //接收数据报   
//         bread = recvfrom(sockRaw,recvbuf,MAX_PACKET,0,(struct sockaddr*)&from,&fromlen);   
//         if(bread == SOCKET_ERROR)   
//         {   
//             if(WSAGetLastError() == WSAETIMEDOUT)   
//             {   
//                 printf("REQUEST timeOut.\n");   
//                 continue;   
//             }   
//             printf("recvfrom failed: %d",WSAGetLastError());   
//             ExitProcess(STATUS_FAILED);   
//         }   
//    
//         if(!decode_resp(recvbuf,bread,&from))   
//             statistic++;        //成功接收的数目   
//         Sleep(1000);   
//     }   
//    
//     //显示统计信息   
//     printf("\nPinging statistics for %s :\n",dest_ip);   
//     printf("    Packets: Sent = %d, Received = %d, Lost = %d (%2.0f%% loss)\n",times,   
//         statistic,(times-statistic),(float)(times-statistic)/times*100);   
//     WSACleanup();   
//     return 0;   
// }   
//    
//    
// void fill_icmp_data(char * icmp_data, int datasize)   
// {   
//     IcmpHeader *icmphdr;   
//     char *datapart;   
//    
//     icmphdr = (IcmpHeader*)icmp_data;   
//    
//     icmphdr->type = ICMP_ECHO;                               //设置类型信息   
//     icmphdr->code = 0;   
//     icmphdr->id = (USHORT)GetCurrentProcessId();         //设置其ID号为当前进程的ID号   
//     icmphdr->seq = 0;   
//     icmphdr->checksum = 0;   
//    
//     datapart = icmp_data + sizeof(IcmpHeader);              //计算出ICMP数据报的数据部分   
//     memset(datapart,'E',datasize - sizeof(IcmpHeader));     //填入数据   
// }   
//    
// USHORT 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);   
// }   
//    
// int decode_resp(char *buf,int bytes,struct sockaddr_in *from)   
// {   
//     IcmpHeader *icmphdr;   
//     IpHeader *iphdr;   
//     unsigned short iphdrlen;   
//    
//     iphdr = (IpHeader *)buf;   
//     iphdrlen = (iphdr->headlen) * 4;                         //IP报头的长度   
//     icmphdr = (IcmpHeader*)(buf+iphdrlen);                      //跳过IP报头   
//    
//     if(bytes < iphdrlen+ICMP_MIN)   
//     {   
//         printf("Too few bytes from %s\n",inet_ntoa(from->sin_addr));   
//         //return 1;                                             //数据包太短,丢弃   
//     }   
//    
//     if(icmphdr->type != ICMP_ECHOREPLY)   
//     {   
//         printf("non-echo type %d recvd\n",icmphdr->type);   
//         return 1;                                               //不是回送响应(ping应答),丢弃   
//     }   
//    
//     if(icmphdr->id != (USHORT)GetCurrentProcessId())   
//     {   
//         printf("someone else's packet!\n");   
//         return 1;                                               //ID号不符,丢弃   
//     }   
//     printf("REPLY FROM %s ",inet_ntoa(from->sin_addr));   
//     printf("%d bytes from %s",bytes,inet_ntoa(from->sin_addr));   
//     printf(" icmp_seq = %d. ",icmphdr->seq);   
//     printf(" time: %d ms ",GetTickCount()-icmphdr->timestamp);   
//     printf("\n");   
//     return 0;   
// }  


第二种

// #include <StdAfx.h>
// #include <stdlib.h>
// #include <stdio.h>
// #include <WINSOCK2.H>
// #include <windows.h>
// 
// 
// #include <ws2tcpip.h> //IP_TTL
// #pragma comment(lib,"ws2_32.lib")
// //ICMP首部结构体
// typedef struct tagICMPHEADER
// {
//  unsigned char type;//类型
//  unsigned char code;//代码
//  unsigned short checknum;//检验和
//  unsigned short id;//标识符
//  unsigned short seq_num;//序列号
// }ICMPHEADER;
// //IP首部结构体
// typedef struct _ip_hdr
// {
//  unsigned char ihl:4;   //首部长度
//  unsigned char version:4; //版本 
//  unsigned char tos;   //服务类型
//  unsigned short tot_len; //总长度
//  unsigned short id;    //标志
//  unsigned short frag_off; //分片偏移
//  unsigned char ttl;   //生存时间
//  unsigned char protocol; //协议
//  unsigned short chk_sum; //检验和
//  struct in_addr srcaddr; //源IP地址
//  struct in_addr dstaddr; //目的IP地址
// }IPHEADER;
// 
// 
// //计算检验和
// unsigned short checksum(unsigned short *buffer, int size) 
// { 
//  unsigned long cksum = 0; // 将所有的16数相加 
//  while (size > 1) 
//  { 
//   cksum += *buffer++;
//   size -= sizeof(unsigned short); 
//  }
//  if (size) //加上最后一个BYTE 
//  {
//   cksum += *(unsigned char*)buffer;
//  } 
//  while (cksum>>16)
//  {
//   cksum = (cksum & 0xffff) + (cksum >> 16);
//  } 
//  return (unsigned short)~cksum;
// } 
//  
//  
// int main()
// {
//  WSADATA wsadata;
//  if(WSAStartup(MAKEWORD(2,2),&wsadata)!=0)
//  {
//   printf("初始化socket dll失败\n");
//   return 1;
//  }
//  //设置ICMP首部内容
//  ICMPHEADER icmp_hdr;
//  icmp_hdr.type=8;
//  icmp_hdr.code=0;
//  icmp_hdr.checknum=0;
//  icmp_hdr.id=(unsigned short)GetCurrentProcessId();
//  icmp_hdr.seq_num=0;
//  //计算检验和
//  icmp_hdr.checknum=checksum((unsigned short*)&icmp_hdr,sizeof(icmp_hdr));
//  //设置原始套接字
//  SOCKET sock=WSASocket(AF_INET,SOCK_RAW,IPPROTO_ICMP,NULL,0,0);
//  if(INVALID_SOCKET==sock)
//  {
//   printf("创建socket失败\n");
//   WSACleanup();
//   return 1;
//  }
//  int ttl=255;
//  //设置TTL为255
//  if(setsockopt(sock,IPPROTO_IP,IP_TTL,(const char*)&ttl,sizeof(ttl))==SOCKET_ERROR)
//  {
//   printf("set TTL error!\n");
//   WSACleanup();
//   return 2;
//  }
//  //目标地址
//  SOCKADDR_IN Dest_addr;
//  memset(&Dest_addr,0,sizeof(Dest_addr));
//  Dest_addr.sin_family=AF_INET;
//  Dest_addr.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
//  //发送ICMP请求报文
//  int status=sendto(sock,(const char*)&icmp_hdr,sizeof(icmp_hdr),0,(SOCKADDR*)&Dest_addr,sizeof(Dest_addr));
//  if(SOCKET_ERROR==status)
//  {
//   printf("sent error!\n");
//   shutdown(sock,SD_BOTH);
//   closesocket(sock);
//   WSACleanup();
//   return 3;
//  }
//  int size=60+sizeof(ICMPHEADER);
//  char *buffer=(char*)malloc(size);
//  memset(buffer,0,size);
//  int des=sizeof(SOCKADDR_IN);
//  //接受ICMP回应报文并分析
//  while (true)
//  {
//   recvfrom(sock,buffer,size,0,(SOCKADDR*)&Dest_addr,&des);
//   ICMPHEADER *p=(ICMPHEADER*)((char*)buffer+((IPHEADER*)buffer)->ihl*4);
//   if(p->type==0)
//   {
//    if(p->id==icmp_hdr.id)
//    {
//     printf("ping %s成功\n",inet_ntoa(Dest_addr.sin_addr));
//     break;
//    }
//   }
//   else
//   {
//    printf("ping %s不成功\n",inet_ntoa(Dest_addr.sin_addr));
//    break;
//   }
//  }
//  shutdown(sock,SD_BOTH);
//  closesocket(sock);
//  WSACleanup();
//  return 0;
// } 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值