系统ping程序的源程序
根据给定的信息,本文将详细解析“系统ping程序的源程序”,主要聚焦于C++编写的ping程序。此程序不仅提供了完整的源代码,而且还包含了丰富的注释,这为理解和学习网络编程提供了一个非常好的示例。 ### 一、概述 本程序是基于Windows平台使用C++语言实现的一个ping命令。它通过Winsock库发送和接收ICMP协议的数据包来测试与目标主机之间的网络连通性。整个程序结构清晰,并且每一部分都添加了详细的注释,非常适合初学者学习和理解网络通信的基本原理。 ### 二、程序核心部分分析 #### 1. 包含的关键头文件 - `winsock2.h`: 提供了Winsock API的定义,用于网络编程。 - `stdlib.h`: 标准库头文件,提供了如内存分配等基础功能。 - `stdio.h`: 标准输入输出库头文件。 #### 2. 定义常量 - `ICMP_ECHO`: 定义ICMP Echo请求消息类型。 - `ICMP_ECHOREPLY`: 定义ICMP Echo应答消息类型。 - `ICMP_MIN`: 定义ICMP数据包的最小长度。 - `DEF_PACKET_SIZE`: 定义默认数据包大小。 - `DEF_PACKET_NUMBER`: 定义默认发送的数据包数量。 - `MAX_PACKET`: 定义最大数据包长度。 #### 3. 数据结构定义 - `IpHeader`: 定义IP数据报头部结构体。 - `h_len`: IP头长度。 - `version`: IP版本号。 - `tos`: 服务类型。 - `total_len`: 总长度。 - `ident`: 标识符。 - `frag_and_flags`: 分段标志。 - `ttl`: 生存时间。 - `proto`: 协议类型。 - `checksum`: IP校验和。 - `sourceIP`: 源IP地址。 - `destIP`: 目标IP地址。 - `IcmpHeader`: 定义ICMP头部结构体。 - `i_type`: ICMP消息类型。 - `i_code`: 错误代码。 - `i_cksum`: ICMP校验和。 - `i_id`: 标识。 - `i_seq`: 序列号。 - `timestamp`: 时间戳。 #### 4. 函数实现 - `fill_icmp_data`: 用于填充ICMP数据。 - `checksum`: 计算ICMP校验和。 - `decode_resp`: 解码响应数据包。 - `Usage`: 显示帮助信息。 - `main`: 主函数,初始化Winsock,创建套接字并发送ICMP请求包。 #### 5. 主函数流程 - 初始化Winsock。 - 创建一个原始套接字。 - 设置目标地址。 - 发送ICMP Echo请求。 - 接收响应。 - 解析响应数据包。 - 输出统计信息。 ### 三、关键技术点 #### 1. Winsock初始化 - 使用`WSAStartup()`函数初始化Winsock环境,指定版本为2.2。 - 如果初始化失败,则调用`ExitProcess()`退出程序。 #### 2. 原始套接字创建 - 使用`WSASocket()`函数创建一个原始套接字,指明地址族为`AF_INET`(IPv4)、套接字类型为`SOCK_RAW`(原始套接字),协议类型为`IPPROTO_ICMP`(ICMP协议)。 #### 3. 发送ICMP数据包 - 构建ICMP数据包:包括IP头部和ICMP头部。 - 使用`sendto()`函数发送构建好的数据包到目标地址。 #### 4. 接收ICMP响应 - 使用`recvfrom()`函数接收ICMP响应。 - 解析接收到的数据包,获取目标主机返回的时间戳等信息。 #### 5. 统计与输出 - 统计发送和接收的数据包数量。 - 计算平均往返时间等统计信息。 - 将统计结果输出到屏幕。 ### 四、总结 该C++编写的ping程序通过对网络通信底层细节的深入探讨,不仅为读者展示了如何在Windows环境下实现一个简单的ping命令,同时也加深了对ICMP协议及其工作原理的理解。此外,由于程序中包含了丰富的注释,这使得即便是初学者也能较为轻松地理解和学习其中涉及的技术要点。
#pragma comment(lib, "ws2_32.lib")
#include "winsock2.h"
#include "stdlib.h"
#include "stdio.h"
#define ICMP_ECHO 8//定义回显报文代码
#define ICMP_ECHOREPLY 0
#define ICMP_MIN 8 //最小8字节ICMP包
/* IP头首部结构 */
typedef struct iphdr {
unsigned int h_len:4; // 首部长度
unsigned int version:4; // IP版本
unsigned char tos; // 服务类型
unsigned short total_len; // 包总长度
unsigned short ident; //标识符
unsigned short frag_and_flags; // 标志
unsigned char ttl;// 生存周期
unsigned char proto; // protocol (TCP, UDP etc) 协议类型
unsigned short checksum; //IP检验和
unsigned int sourceIP;//源地址IP
unsigned int destIP;//目的地址IP
}IpHeader;
//
// ICMP 首部结构
//
typedef struct icmphdr {
BYTE i_type;//类型
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 DEF_PACKET_NUMBER 4 /* 发送数据报的个数 */
#define MAX_PACKET 1024 //最大ICMP大小
#define xmalloc(s) HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,(s))
#define xfree(p) HeapFree (GetProcessHeap(),0,(p))
void fill_icmp_data(char *, int);
USHORT checksum(USHORT *, int);
int decode_resp(char *,int ,struct sockaddr_in *);
void Usage(char *progname){
fprintf(stderr,"Usage:\n");
fprintf(stderr,"%s [number of packets] [data_size]\n",progname);
fprintf(stderr,"datasize can be up to 1Kb\n");
ExitProcess(STATUS_FAILED);//结束此进程返回给父进程值
}
/*主函数
agrc : 参数的个数 ,默认为一
agrv : 参数的内容 ,用于传递输入的IP地址
调试方法:在CMD命令行中到该程序的子目录打xping 127.0.0.1(IP地址任意)
剩余9页未读,继续阅读
- 粉丝: 1
- 资源: 12
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
- 1
- 2
前往页