Windows系统ping命令的c++实现

news2024/11/26 3:32:06
// ping.cpp : 定义控制台应用程序的入口点。
//

#include <winsock2.h> 
#include <stdio.h> 
#include <stdlib.h> 

#define ICMP_ECHO 8 
#define ICMP_ECHOREPLY 0 

/* The IP header */ 
typedef struct iphdr 
{ 
    unsigned char h_len:4; // length of the header 
    unsigned char 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; 

#define STATUS_FAILED 0xFFFF 
#define DEF_PACKET_SIZE 32 
#define MAX_PACKET 1024 

/* The response is an IP packet. We must decode the IP header to locate the ICMP data */ 
void decode_resp(char *buf, int bytes,struct sockaddr_in *from)
{
    IpHeader *iphdr; 
    IcmpHeader *icmphdr; 
    unsigned short iphdrlen; 

    iphdr=(IpHeader*)buf; 
    iphdrlen=sizeof(IpHeader)+sizeof(IcmpHeader);

    if(bytes<iphdrlen) 
    { 
        printf("Too few bytes from %s\n",inet_ntoa(from->sin_addr)); 
    } 

    icmphdr=(IcmpHeader*)(buf+sizeof(IpHeader)); 
    if(icmphdr->i_type!=ICMP_ECHOREPLY) 
    { 
        fprintf(stderr,"non-echo type %d recvd\n",icmphdr->i_type); return; 
    }

    if(icmphdr->i_id!=(USHORT)GetCurrentProcessId()) 
    { 
        fprintf(stderr,"someone else's packet!\n"); return ; 
    }

    int correct=0;
    for(int k=0;k<bytes-iphdrlen;k++)
    {
        if(*(buf+iphdrlen+k)=='E')
        {
            correct++;
        }
    }

    printf("来自 %s 的回复: 字节=%d 时间=%dms TTL=%d\n",\
    inet_ntoa(from->sin_addr),correct,GetTickCount()-icmphdr->timestamp,iphdr->ttl); 
} 

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); 
} 

/* Helper function to fill in various stuff in our ICMP request. */ 
void fill_icmp_data(char *icmp_data, int datasize)
{ 
    char *datapart=NULL; 
    IcmpHeader *icmp_hdr=NULL; 
    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++; 
    icmp_hdr->timestamp=GetTickCount(); 
    datapart=icmp_data+sizeof(IcmpHeader); // Place some junk in the buffer. 
    memset(datapart,'E',datasize-sizeof(IcmpHeader)); 
    icmp_hdr->i_cksum=checksum((USHORT*)icmp_data,datasize);
} 

int main(int argc, char *argv[])
{ 
    int count=1;
    int error=-1;
    int datasize=0; 
    int timeout=3000; 
    struct sockaddr_in addrServer; 
    struct hostent *phostent=NULL; 
    int destlen=sizeof(addrServer); 
    char *dest_ip=NULL; 
    char icmp_data[MAX_PACKET]; 
    char recvbuf[MAX_PACKET]; 
    unsigned int addr=0; 
    char srcIP[MAX_PATH]="0.0.0.0";
    char dstIP[MAX_PATH]="127.0.0.1";

    for(int n=1;n<argc;)
    {
        if(!strcmp(argv[n],"-S"))
        {            
            n++;strcpy_s(srcIP,argv[n++]);
        }
        else if(!strcmp(argv[n],"-n"))
        {
            n++;count=atoi(argv[n++]);
        }
        else
        {
            strcpy_s(dstIP,argv[n++]);
        }
    }

    WSADATA wsaData={0}; 
    if(WSAStartup(MAKEWORD(1,1),&wsaData)!=0)
    { 
        printf("WSA startup error\n"); 
        ExitProcess(STATUS_FAILED); 
    } 

    SOCKET sockClient=WSASocket(AF_INET, SOCK_RAW, IPPROTO_ICMP, NULL, 0,0); 
    if(sockClient==INVALID_SOCKET) 
    { 
        printf("WSA socket error\n"); 
        ExitProcess(STATUS_FAILED); 
    } 

    sockaddr_in addrClient;
    addrClient.sin_addr.S_un.S_addr=inet_addr(srcIP);

    addrClient.sin_family=AF_INET;
    addrClient.sin_port=htons(0);

    error=bind(sockClient,(SOCKADDR *)&addrClient,sizeof(addrClient));
    if(error)
    {
        closesocket(sockClient);
        printf("bind client error\n");
        return WSACleanup();
    }

    unsigned long ul=true;
    error=ioctlsocket(sockClient,FIONBIO,(unsigned long*)&ul);
    if(error)
    {
        closesocket(sockClient);
        printf("set ioctlsocket error\n");
        return WSACleanup();
    }

    error=setsockopt(sockClient,SOL_SOCKET,SO_RCVTIMEO,(char*)&timeout, sizeof(timeout)); 
    if(error==SOCKET_ERROR) 
    { 
        fprintf(stderr,"failed to set recv timeout: %d\n",WSAGetLastError()); 
        ExitProcess(STATUS_FAILED); 
    } 

    error=setsockopt(sockClient,SOL_SOCKET,SO_SNDTIMEO,(char*)&timeout, sizeof(timeout)); 
    if(error==SOCKET_ERROR) 
    { 
        fprintf(stderr,"failed to set send timeout: %d\n",WSAGetLastError()); 
        ExitProcess(STATUS_FAILED); 
    } 

    memset(&addrServer,0,sizeof(addrServer)); 
    phostent=gethostbyname(dstIP); 
    if(!phostent)
    { 
        addr=inet_addr(dstIP); 
    } 

    if((!phostent)&&(addr==INADDR_NONE)) 
    { 
        fprintf(stderr,"Unable to resolve host %s\n",dstIP); 
        ExitProcess(STATUS_FAILED); 
    } 

    if(phostent!=NULL) 
    {
        memcpy(&(addrServer.sin_addr),phostent->h_addr,phostent->h_length);
    }
    else
    {
        addrServer.sin_addr.s_addr=addr; 
    }

    if(phostent) 
    {
        addrServer.sin_family=phostent->h_addrtype;
    }
    else
    {
        addrServer.sin_family=AF_INET; 
        dest_ip=inet_ntoa(addrServer.sin_addr);
    } 

    datasize=DEF_PACKET_SIZE; 
    datasize+=sizeof(IcmpHeader); 
    memset(icmp_data,0,MAX_PACKET);

    for(int i=0;i<count;i++) 
    {         
        fill_icmp_data(icmp_data,datasize); 
        int num=sendto(sockClient,icmp_data,datasize,0,(struct sockaddr*)&addrServer, sizeof(addrServer)); 
        if(num==SOCKET_ERROR)
        { 
            error=WSAGetLastError();
            if(error==WSAETIMEDOUT) 
            { 
                fprintf(stderr,"errorcode=%d\n",error); 
                continue; 
            }
        } 
        if(num<datasize) 
        { 
            fprintf(stdout,"Write %d bytes\n",num); 
        }

        timeval tm;
        int len=sizeof(int);
        fd_set set;

        for(int k=0;k<3;k++)
        {
            num=recvfrom(sockClient,recvbuf,MAX_PACKET,0,(struct sockaddr*)&addrServer, &destlen); 
            if(num!=SOCKET_ERROR)
            {
                break;
            }

            if(num==SOCKET_ERROR)
            {    
                Sleep(1);
                tm.tv_sec=0;        
                tm.tv_usec=1;        
                FD_ZERO(&set);        
                FD_SET(sockClient,&set);        
                if(select(sockClient,NULL,&set,NULL,&tm)>0)        
                {            
                    getsockopt(sockClient,SOL_SOCKET,SO_ERROR,(char*)&error,&len);            
                }                
            }
        }

        if(num!=SOCKET_ERROR)
        {
            decode_resp(recvbuf,num,&addrServer); 
        }
        else
        {
            printf("Can not find host %s\n",dstIP); 
        }
        if(i>0)
        {
            Sleep(1000);
        }
    } 

    closesocket(sockClient);
    WSACleanup();

    return 0; 
}

编译命令如下:

g++ -std=c++2a -o ping.exe ping.cpp -lws2_32

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1042812.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

什么是内容运营?

关于内容运营&#xff0c;在不同种类的公司&#xff0c;侧重点也不一样。 电商平台的内容运营岗更偏内容营销&#xff1b;产品功能比较简单的公司&#xff0c;内容运营和新媒体运营的岗位职责差不多&#xff1b;而内容平台的内容运营更多的是做内容的管理和资源整合。

使用ElementUI结合Vue完善主页的导航菜单和书籍管理的后台数据分页查询

目录 一、动态树 ( 1 ) 数据表 ( 2 ) 后端 ( 2 ) 前端 二、书籍管理 数据表 后端 前端 ElementUI的背景 是一套基于Vue.js的桌面端组件库&#xff0c;由饿了么前端团队开发维护。它提供了丰富的UI组件和交互效果&#xff0c;可以帮助开发者快速构建出美观、易用的We…

第77步 时间序列建模实战:多因素预测 vol-2(以ARIMA为例)

基于WIN10的64位系统演示 一、写在前面 上一期&#xff0c;我们构建了多变量的ARIMA时间序列预测模型&#xff0c;其实人家有名字的&#xff0c;叫做ARIMAX模型&#xff08;X就代表解释变量&#xff09;。 这一期&#xff0c;我们介绍其他机器学习回归模型如何建立多变量的时…

『C语言进阶』qsort函数及模拟实现

&#x1f525;博客主页&#xff1a; 小羊失眠啦 &#x1f516;系列专栏&#xff1a; C语言 &#x1f325;️每日语录&#xff1a;没有退路&#xff0c;只能让自己变得强大 ❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 前言 在上篇指针进阶中&#xff0c;我们对函数指针、函数…

深入理解 Swift 新并发模型中 Actor 的重入(Reentrancy)问题

问题现象 我们知道,Swift 5.5 引入的新并发模型极大简化了并行逻辑代码的开发,更重要的是:使用新并发模型中的 Actor 原语可以大大降低并发数据竞争的可能性。 不过,即便 Actor 有如此神奇之功效,它也不是“万能药”,仍不能防止误用带来的问题。比如:Actor 重入(Reen…

132.【MySQL_进阶篇】

MySQL_进阶 (一)、存储引擎1.MySQL体系结构(1).连接层(2).服务层(3).引擎层(4).存储层 2.存储引擎简介(1).查看某张表的数据引擎(2).展示此版本支持的所有存储引擎(3).创建表my_myisam,并指定MyIASM存储引擎(4).存储引擎示列 3.存储引擎 _ Innodb(1).Innodb 介绍(2).Innodb 特点…

通过 HelpLook ChatBot AI自动问答机器人降低客户服务成本

在当今竞争激烈的商业环境中&#xff0c;提供卓越的客户服务对于维持忠诚的客户群和推动业务增长至关重要。客户服务涵盖了公司与其客户之间的所有互动&#xff0c;包括解答问题、解决问题和提供支持。它在塑造客户对品牌的看法方面起着关键作用&#xff0c;并且可以显著影响他…

NSSSCTF做题(2)

1.[BJDCTF 2020]easy_md5 打开页面发现没什么东西&#xff0c;只有一个提交表单&#xff0c;然后url会显示你提交的信息 源代码里也看不到什么 &#xff0c;用dirsearch扫一下&#xff0c;这些是扫出来的数据 抓包看到了提示 hint: select * from admin where passwordmd5($pas…

【文件操作——详细讲解】

1. 为什么使用文件&#xff1f;&#x1f9d0; 如果没有⽂件&#xff0c;我们写的程序的数据是存储在电脑的内存中&#xff0c;如果程序退出&#xff0c;内存回收&#xff0c;数据就丢失了&#xff0c;等再次运⾏程序&#xff0c;是看不到上次程序的数据的&#xff0c;如果要将数…

cmd下scala退出命令

cmd下scala退出命令 &#xff1a;quit

checksec使用

checksec Relro&#xff1a;Full Relro&#xff08;重定位表只读&#xff09; Relocation Read Only&#xff0c; 重定位表只读。重定位表即.got 和 .plt个表。 Stack&#xff1a;No Canary found&#xff08;能栈溢出&#xff09; 栈保护。栈溢出保护是一种缓冲区溢出攻击缓解…

Docker 部署前端项目(非自动化)

部署前端项目 1. nginx配置文件1.1 nginxConf 2. 创建容器2.1 添加项目2.2 下载项目依赖2.3 打包前端项目2.4 创建容器2.5 查看容器 3. 视频演示4. 注意 1. nginx配置文件 1.1 nginxConf 首先你需要有nginx配置文件&#xff0c;你可以执行以下命令获取配置文件 # 安装镜像-生成…

JS进阶-闭包

概念&#xff1a;一个函数对周围状态的引用捆绑在一起&#xff0c;内层函数中访问到其外层函数的作用域 简单理解&#xff1a;闭包&#xff08;Closure&#xff09;内层函数外层函数的变量 function outer() {const a 1function f() {console.log(a)}f()} outer() 闭包作用…

最新商道融绿ESG数据(2015-2023)

数据简介&#xff1a;环境、社会和公司治理&#xff08;environmental, social, and corporate governance, 简称ESG&#xff09;方面的非财务信息已经普遍被用于评估企业在可持续发展方面的绩效。投资者通过考察上市公司的ESG绩效&#xff0c;便于识别企业面临的风险&#xff…

L1-033 出生年 c++解法

一、题目再现 以上是新浪微博中一奇葩贴&#xff1a;“我出生于1988年&#xff0c;直到25岁才遇到4个数字都不相同的年份。”也就是说&#xff0c;直到2013年才达到“4个数字都不相同”的要求。本题请你根据要求&#xff0c;自动填充“我出生于y年&#xff0c;直到x岁才遇到n个…

ElementUI之动态树+数据表格+分页

目录 一.ElementUI动态树 编写left.vue界面 配置url ​编辑 建立书籍的页面 编写路由 显示子主键的类 测试结果 二.ElementUI数据表格分页 在booklist中编写数据表格和分页 编写url路径 测试结果 ​编辑 一.ElementUI动态树 编写left.vue界面 <template>…

OpenAI 更新 ChatGPT:支持图片和语音输入【附点评】

一、消息正文 9月25日消息,近日OpenAI宣布其对话AI系统ChatGPT进行升级,添加了语音输入和图像处理两个新功能。据OpenAI透露,这些新功能将在未来两周内面向ChatGPT Plus付费用户推出,免费用户也将很快可以使用这些新功能。这标志着ChatGPT继续朝着多模态交互的方向发展,为用户提…

3D 视觉市场空间广阔,3D 感知龙头全技术路线布局

3D 视觉市场尚处在发展早期,空间广阔 人类 70%以上信息通过眼睛获取,对于机器而言,视觉感知也是其“智能化”升级的重要基础。3D 成像让每一个像素除 x、y 轴数据外,还有 z 轴(深度/距离)数据。围绕着人体、物体、空间扫描一圈,就能得到点云图和精准的“1:1”还原的 3D …

abaqus命令行基础

1.abaqus命令行基础 使用 abaqus 时&#xff0c;如果需要进行参数分析&#xff0c;就需要生成大量的模型&#xff0c;这时一般会使用python文件定义函数进行批量生成并计算。 如果已经生成了计算文件(*.inp文件)&#xff0c;那么就可以直接在命令行进行求解&#xff0c;abaqu…

自动化测试框架pytest命令参数

【软件测试面试突击班】如何逼自己一周刷完软件测试八股文教程&#xff0c;刷完面试就稳了&#xff0c;你也可以当高薪软件测试工程师&#xff08;自动化测试&#xff09; 失败后停止 使用下面的参数可以让测试在第1(N)次测试失败后停止&#xff1a; pytest ‐x # 第一次测试…