#include "ping.h"//icmp包的组成
struct icmp
{unsigned char type;unsigned char code;unsigned short chksum;unsigned short id;unsigned short seq;unsigned long tv_sec;//秒unsigned long tv_usec;//微妙unsigned char unused[DATASIZE];
};
/**********************
函数名:
功能:
参数:
返回值:
**********************/
unsigned short Ping_calchecksum(char *buffer, int len)
{unsigned short *p = (unsigned short *)buffer;unsigned int sum = 0;int i = 0;for (i = 0; i < len/2; i++) {sum += *p;p++;}sum += (sum >> 16);return ~sum;
}/**********************
函数名:
功能:
参数:
返回值:
**********************/
int Ping_pack(int pack_no)
{bzero(&g_icmp_data, sizeof(g_icmp_data));g_icmp_data.type = PA_RESQUST;g_icmp_data.code = 0;g_icmp_data.chksum = 0;g_icmp_data.id = 0;g_icmp_data.seq = 0;struct timeval tv;gettimeofday(&tv, NULL); g_icmp_data.tv_sec = tv.tv_sec;g_icmp_data.tv_usec = tv.tv_usec;memset(g_icmp_data.unused, 0, DATASIZE);g_icmp_data.chksum = Ping_calchecksum((char *)&g_icmp_data, sizeof(g_icmp_data));return 0;
}/*********************
函数名:Ping_mysend
功能:发送ICMP请求报文
参数:num 发送请求包的次数
返回值:0
**********************/
int Ping_mysend(int num)
{int packetsize = 0;int i = 0;char ch = 0;int rlen = 0;for (i = 0; i < num; i++){packetsize = Ping_pack(i);if (sendto(g_sockfd, &g_icmp_data, sizeof(g_icmp_data), 0, (struct sockaddr *)&g_ser, sizeof(g_ser)) < 0){perror("sendto");continue;}else{g_begin++;sleep(1);}}return 0;
}void* send_data(void* arg)
{int num = 0;if (0 == g_array[0]){Ping_mysend(PING_A);   }else if (0 == strncmp(g_array, "-a", 2)){Ping_mysend(PING_A);}else if (0 == strncmp(g_array, "-t", 2)){Ping_mysend(PING_T);}else if (0 == strncmp(g_array, "-n", 2)){num = Ping_gettimeofn(); Ping_mysend(num);}return    NULL;
}/**********************
函数名:Ping_gettimeofn
功能:获得ping -n conut 参数conut的值
返回值: sum
**********************/
int Ping_gettimeofn()
{int sum = 0;sum = atoi(g_nconut);return sum;
}/**********************
函数名:Ping_myrecv
功能:接收icmp回复报文
参数:num
返回值:接收的次数,依据参数和发送的次数定
**********************/
int Ping_myrecv(int num)
{int rlen = 0;int i = 0;char ch = 0;int ret = 0;while (i < num){memset(g_buffer_recv, 0, sizeof(g_buffer_recv));rlen = recv(g_sockfd, g_buffer_recv, sizeof(g_buffer_recv), 0);if (rlen < 0){printf("fail to recv!\n");continue;}i++;    ret = Ping_unpack(rlen);if (-1 == ret){continue;}else{g_end++;}    }return 0;
}void* recv_data(void *arg)
{int num = 0;if (0 == g_array[0]){Ping_myrecv(PING_A);   }else if (0 == strncmp(g_array, "-a", 2)){Ping_myrecv(PING_A);}else if (0 == strncmp(g_array, "-t", 2)){Ping_myrecv(PING_T);}else if (0 == strncmp(g_array, "-n", 2)){num = Ping_gettimeofn();Ping_myrecv(num);}return NULL;
}/**********************
函数名:Ping_unpack
功能:解析响应数据包、判断是否返回正常
参数:len 响应数据包长度
返回值:成功返回0,失败返回-1
**********************/
int Ping_unpack(int len)
{double rtt = 0;struct timeval tv_cur;struct ip *myip;struct icmp *myicmp;int ipsize = 0; char *recv_ip = NULL;myip = (struct ip*)g_buffer_recv;ipsize = (myip->ip_hl)<<2;recv_ip = (char *)inet_ntoa(myip->ip_src);len -= ipsize;myicmp = (struct icmp *)(g_buffer_recv + ipsize);if (len < UP_ICMPHEAD)   {perror("ICMP packets length is less than 8\n");return -1;}else if(strcmp(g_ip, recv_ip)) {return -1;}    else if (myicmp->type != 0) {return -1;}    else{gettimeofday(&tv_cur, NULL);rtt = (tv_cur.tv_sec - g_icmp_data.tv_sec)*1000 + (tv_cur.tv_usec - g_icmp_data.tv_usec)/1000.0f;g_totaltime += rtt;if (rtt > g_maxtime){g_maxtime = rtt;}   if (rtt < g_mintime){g_mintime = rtt;}printf("%d byte from %s: icmp_seq=%u ttl=%d rtt=%0.1fms\n", g_datalen + UP_ICMPHEAD, inet_ntoa(g_ser.sin_addr), g_end,  myip->ip_ttl, rtt);}return 0;
}/**********************
函数名:sig_int
功能:收到结束线程信号后,打印数据
参数:signo
**********************/
void sig_int(int signo)
{double perce = 0;perce = (g_begin - g_end) / g_begin;printf("---ping %s is complete--- \n %d was sended and %d was received, %0.1lf%%packet loss, time %0.1fms rtt\n min/avg/max = %0.1f/%0.1f/%0.1f ms \n", g_tmpbuff, g_begin, g_end, perce * 100 , g_totaltime, g_mintime, g_totaltime/g_begin, g_maxtime);exit(0);
}int main(int argc, char *argv[])
{double number = 0;struct hostent *ent = NULL;pthread_t pid1 = 0, pid2 = 0;signal(SIGINT, sig_int);snprintf(g_tmpbuff, sizeof(g_tmpbuff), "%s", argv[1]);if (argc < 2){return -1;}if (argv[1] == NULL){perror("fail to ping!");return -1;}if (argc > 2){memset(g_array, 0, sizeof(g_array));memset(g_nconut, 0, sizeof(g_nconut));snprintf(g_array, sizeof(g_array), "%s", argv[2]);}if (argc > 3){    if (0 == strncmp(g_array, "-n", 2)){snprintf(g_nconut, sizeof(g_nconut), "%s", argv[3]); }}   ent = gethostbyname(argv[1]);if (NULL == ent){printf("ping: unknown host %s\n", argv[1]);exit(-1);}inet_ntop(AF_INET, ent->h_addr, g_ip, sizeof(g_ip));  //将二进制的32位ip地址转换成字符串的点分十进制g_sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);//设置目标地址bzero(&g_ser, sizeof(g_ser));g_ser.sin_family = AF_INET;inet_pton(AF_INET, g_ip, &g_ser.sin_addr); //把点分十进制转化成二进制地址printf("PING %s (%s) %d bytes of data.\n", g_tmpbuff, g_ip, g_datalen);//创建线程进行收发数据if(pthread_create(&pid1, NULL, send_data, NULL) < 0){perror("pthread_create");return -1;}if(pthread_create(&pid2, NULL, recv_data, NULL) < 0){perror("pthread_create");return -1;}pthread_join(pid1, NULL);pthread_join(pid2, NULL);number = (g_begin - g_end) * 100 / g_begin;printf("---ping %s is complete--- \n %d was sended and %d was received, %0.1lf%%packet loss, time %0.1fms \n min/avg/max = %0.1f/%0.1f/%0.1f ms \n", argv[1], g_begin, g_end, number, g_totaltime, g_mintime, g_totaltime/g_begin, g_maxtime);close(g_sockfd);return 0;
}
头文件#ifndef PING__H_
#define PING__H_#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/select.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netdb.h>
#include <sys/time.h>
#include <signal.h>
#include <netinet/ip.h>
#include <netinet/in.h>
#include <pthread.h>#define BUFFER_SIZE       512
#define MAX_SIZE          56
#define ARRAY_SIZE        12
#define NCONUT_SIZE       12
#define ARGV1             128
#define MINSIZE           1000
#define DATASIZE          48
#define PING_A            4
#define PING_T            100
#define UP_ICMPHEAD       8
#define PA_RESQUST        8struct icmp g_icmp_data;
struct sockaddr_in g_ser;
int g_begin = 0;
int g_end = 0;
int g_sockfd = 0;
char g_buffer_recv[BUFFER_SIZE] = {0};
int g_datalen = MAX_SIZE;
char g_array[ARRAY_SIZE] = {0};
char g_nconut[NCONUT_SIZE] = {0};
char g_tmpbuff[ARGV1] = {0};
double g_totaltime = 0;
double g_maxtime = 0;
double g_mintime = MINSIZE;
char g_ip[32] = {0};int Ping_compareInput();
int Ping_gettimeofn();
unsigned short Ping_calchecksum(char *buffer, int len);
int Ping_pack(int pack_no);
int Ping_mysend();
int Ping_myrecv();
int Ping_unpack(int len);#endif

ping C语言实现相关推荐

  1. linux c程序中判断能不能ping,c语言源码ping ip通不通 检测摄像头在不在线 立即返回结果linux...

    #include /* 执行命令,并赋值@reslut */ void executeCMD(const char *cmd, char *result, unsigned long resultLe ...

  2. c语言循环写回合制小游戏_【资源】60个C语言项目源码免费领取!

    序言 今天的资源特意是为大三.大四的童鞋准备的, 整理了一波有关于C语言开发的游戏.系统.效果.小项目的源码!!源码!!源码!! 小编之前发过一波毕业项目的资源, 还没有获取的伙伴,直接申请进群就能获 ...

  3. 用C语言实现Ping程序功能

    本文转载自:http://www.ibm.com/developerworks/cn/linux/network/ping/ ping命令是用来查看网络上另一个主机系统的网络连接是否正常的一个工具.p ...

  4. 用C语言实现linux的ping,用C语言实现Ping程序功能

    大部分人用ping命令只是作为查看另一个系统的网络连接是否正常的一种简单方法. 在这篇文章中,作者将介绍如何用C语言编写一个模拟ping命令功能的程序. ping命令是用来查看网络上另一个主机系统的网 ...

  5. C语言实现与功能的程序,用C语言实现Ping程序功能

    2001 年 10 月 01 日 大部分人用ping命令只是作为查看另一个系统的网络连接是否正常的一种简单方法.在这篇文章中,作者将介绍如何用C语言编写一个模拟ping命令功能的程序. ping命令是 ...

  6. C语言实现ICMP协议Ping命令

    From: http://www.360doc.com/content/12/0429/19/1317564_207540510.shtml 大部分人用ping命令只是作为查看另一个系统的网络连接是否 ...

  7. 用C语言实现Ping命令

    测试环境: Target: x86_64-linux-gnu gcc version 5.3.1 20160413 (Ubuntu 5.3.1-14ubuntu2.1) [引言] 前几天脑子里忽然蹦出 ...

  8. ping程序的C语言源代码

    目录 C语言源代码 ping.c Makefile 编译并运行 C语言源代码 ping.c /** P I N G . C** Using the InterNet Control Message P ...

  9. 用C语言实现Ping程序功能---转

    ping命令是用来查看网络上另一个主机系统的网络连接是否正常的一个工具.ping命令的工作原理是:向网络上的另一个主机系统发送ICMP报文,如果指定系统得到了报文,它将把报文一模一样地传回给发送者,这 ...

  10. C语言实现ICMP协议,并进行PING测试

    目录 myicmpping.c 测试 myicmpping.c /* Copyright (C) Rong Tao @Sylincom Beijing, 2019年 06月 14日 星期五 09:06 ...

最新文章

  1. linux之用 grep -r 关键字
  2. CentOS 5.5高负载下,网卡会自动断开
  3. 【原创】iframe与父页面之间,变量、方法互相调用
  4. python怎么打印字典_在python中打印字典的原始输入顺序
  5. 软件工程第二次作业(原型设计)
  6. 【云小课】基础服务第25课 容灾演练:平时多练兵,急时保可用!
  7. Linux如何实现自动文件同步?
  8. wordpress电商独立站模板
  9. 科学计算机化弧度,弧度与角度换算工具
  10. 如何将Nios II硬件和软件合成一个文件(NIOS II)烧进EPCS falsh
  11. opencv区域提取
  12. 微软新版edge浏览器如何开启画中画模式 (微软新版edge)
  13. 安装打印机显示域服务器不可用,Win7系统打印出错提示“Active Directory域服务当前不可用”怎么解决...
  14. win10蓝牙开关不见了_山灵MW200评测:玩转高清蓝牙全编码,MMCX换线耳机必备升级线...
  15. sql注入之万能密码总结
  16. Fabric-Samples运行createChannel时出现Error: Post “https://localhost:7053/participation/v1/channels“解决办法
  17. 玩游戏也能赚钱?还有这种操作?
  18. 不动产测绘数据入库_不动产测绘中常见的问题及处理方法
  19. 「4」线性代数(期末复习)
  20. 草料二维码如何在多行业实现管理和自动化工作

热门文章

  1. 信号与系统实验一:基本信号的产生和实现
  2. 瑞利分布与瑞利衰落信道
  3. C++调用VSS API进行快照
  4. 《DO圣堂刺客2》国服首测今天拉开
  5. 【数字电路基础】——逻辑门电路
  6. 算法在计算机中的作用
  7. 九曲黄河万里沙,浪淘风簸自天涯 — 正则表达式
  8. 帝豪云星外对接SWAPIDC教程
  9. 硬件信息修改工具 支持修改机器码 硬盘 MAC 等信息
  10. python 读取地震道头数据_通过计算机编程快速读取地震数据的方法