Winsock编程接口实验:实现ping

书上的代码,根据自己的理解对书上代码进行了一部分的更改,并尝试在一些地方使用C++改写。改进程序实现能同时对多个域名进行解析

《Windows网络编程(第2版)》

#define _WINSOCK_DEPRECATED_NO_WARNINGS

#include <winsock2.h>
#pragma comment(lib, "Ws2_32.lib")

#include<iostream>
#include<sstream>

using namespace std;

#define ICMP_MIN 8					// ICMP包的最小长度为8个字节,只包含包头
#define DEF_PACKET_SIZE 32			// 执行ping操作时指定发送数据包的缺省大小
#define MAX_PACKET 1024				// 执行ping操作时指定发送数据包的最大大小
#define ICMP_ECHO 8					// 表示ICMP包为回射请求包
#define ICMP_ECHOREPLY 0			// 表示ICMP包为回射应答包

// IP数据包头结构
typedef struct iphdr {
   
	unsigned int h_len : 4;					// 包头长度
	unsigned int version : 4;				// IP协议版本
	unsigned char tos;						// 服务类型(TOS)
	unsigned short total_len;				// 包的总长度
	unsigned short ident;					// 包的唯一标识
	unsigned short frag_and_flags;			// 标识
	unsigned char ttl;						// 生存时间(TTL)
	unsigned char proto;					// 传输协议 (TCP, UDP等)
	unsigned short checksum;				// IP校验和

	unsigned int sourceIP;
	unsigned int destIP;
}IpHeader;

//ICMP数据包结构
typedef struct _ihdr {
   
	BYTE i_type;							// 类型
	BYTE i_code;							// 编码
	USHORT i_cksum;							// 检验和
	USHORT i_id;							// 编号
	USHORT i_seq;							// 序列号
	ULONG timestamp;						// 时间戳
}IcmpHeader;

// 计算ICMP包的校验和
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);
}

// 对返回的IP数据包进行解码,定位到ICMP数据
// 因为ICMP数据包含在IP数据包中
int decode_resp(char* buf, int bytes, struct sockaddr_in* from, DWORD tid)
{
   
	IpHeader* iphdr;					// IP数据包头
	IcmpHeader* icmphdr;				// ICMP包头
	unsigned short iphdrlen;			// IP数据包头的长度
	iphdr = (IpHeader*)buf;				// 从buf中IP数据包头的指针,接收的数据

	// 计算IP数据包头的长度 
	iphdrlen = iphdr->h_len * 4;		// number of 32-bit words *4 = bytes
	// 如果指定的缓冲区长度小于IP包头加上最小的ICMP包长度,则说明它包含的ICMP数据不完整,或者不包含ICMP数据
	if (bytes < iphdrlen + ICMP_MIN) {
   
		return -1;
	}

	// 定位到ICMP包头的起始位置
	icmphdr = 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值