Windows平台Ping示例源码分析(C/C++)

http://unliminet.blog.51cto.com/380895/77717

 

//-----------------------iphdr.h-----------------------//
//源码分析将忽略ipv6

 

//边界 对齐至字节
#include <pshpack1.h>


pshpack1.h为官方头文件,不做赘述。

// 1 -- ipv4 头部
typedef struct ip_hdr
{
    unsigned char   ip_verlen;        // 前4位 IP 版本号 (IPv4 或者 IPv6)
                                    // 后4位头部长度(32位,4字节)(1.1)
    unsigned char   ip_tos;           // 前3位为优先级,后5位为服务类型(1.2)
    unsigned short ip_totallength;   // 16 位包总长度包括头部和数据(字节)(1.3)
    unsigned short ip_id;            // 16 ID 标识
    unsigned short ip_offset;        // 前3位为分段标识,后5位为分段偏移
    unsigned char   ip_ttl;            // 该包可经过的路由器数量上限
    unsigned char   ip_protocol;      // 协议类型( TCP UDP ICMP IGMP 等)
    unsigned short ip_checksum;      // ipv4 头部的校验和
    unsigned int    ip_srcaddr;       // ipv4 源地址
    unsigned int    ip_destaddr;      // ipv4 目的地址
} IPV4_HDR, *PIPV4_HDR, FAR * LPIPV4_HDR;

此为IPv4头部定义。IPv4头部一般为20字节大小除非使用到选项位。

(1.1) 由于最大头部的限制,ping所具有路由记录功能在如今的网络拓扑中无法使用(只能记录9个ipv4地址)。
此功能 由traceroute替代。

(1.2) 以上参照CCNA Study Guide的说法。在TCP/IP illustrated Volume I中前3位被忽略,后4位分别代表minimize delay, maximize throughput, maximize reliability, 和minimize monetray cost,最后1位被置0并忽略。

(1.3) 理论上ipv4可以达到的最大长度为65536字节,除了在超级通道(hyperchannel)中出现这种最大传输单元外,在普通网络中通常只允许 8192字节大小的包传输。TCP为流协议没有大小限制,UDP最大包为512字节。一台主机一次可接收的最大数据包为576字节。

// 2 -- ipv4 选项头部
typedef struct ipv4_option_hdr
{
    unsigned char    opt_code;          // ipv4 选项头类型
    unsigned char    opt_len;           // ipv4 选项头长度
    unsigned char    opt_ptr;           // ipv4 选项头指针
    unsigned long    opt_addr[9 ];       // ipv4 9个地址列表(2.1)
} IPV4_OPTION_HDR, *PIPV4_OPTION_HDR, FAR *LPIPV4_OPTION_HDR;

(2.1) 参照(1.1)

// 3 -- icmp 头部
typedef struct icmp_hdr
{
    unsigned char    icmp_type;            // icmp 类型
    unsigned char    icmp_code;            // ipv4 码
    unsigned short   icmp_checksum;        // icmp 头部及数据校验和
    unsigned short   icmp_id;              // icmp id标识(3.1)
    unsigned short   icmp_sequence;        // icmp 序列号,请求回应消息对
} ICMP_HDR, *PICMP_HDR, FAR *LPICMP_HDR;

(3.1) id标识一般为发送icmp回显请求的进程号

// 4 -- udp 头部(此头部未在程序中用到)
typedef struct udp_hdr
{
    unsigned short src_portno;            // 源端口
    unsigned short dst_portno;            // 目的端口
    unsigned short udp_length;            // udp 包总长度(字节)
    unsigned short udp_checksum;          // udp 头部以及数据校验和(4.1)
} UDP_HDR, *PUDP_HDR;

(4.1) UDP,TCP校验和都包括头部和数据。IP校验和只涉及头部。UDP校验和可选,TCP为强制。
// 5 -- ipv4  路径记录宏
#define IP_RECORD_ROUTE     0x7            

// icmp 类型和码(5.1)
#define ICMPV4_ECHO_REQUEST_TYPE   8        // icmp  回显请求类型
#define ICMPV4_ECHO_REQUEST_CODE   0         // icmp  回显请求码
#define ICMPV4_ECHO_REPLY_TYPE     0         // icmp  回显回应类型
#define ICMPV4_ECHO_REPLY_CODE     0         // icmp  回显回应码
#define ICMPV4_MINIMUM_HEADER      8        // icmp  最小头部

(5.1) 参照TCP/IP Illustrated : Volume 1 Chapter 6 ICMP   ICMP 消息类型

// 恢复默认对齐方式
#include <poppack.h>

//-----------------------resolve.h---------------------//

#ifndef _RESOLVE_H_
#define _RESOLVE_H_
// 在C++编译器中以C语言的方式编译
#ifdef _cplusplus
extern "C" {
#endif
 
int               PrintAddress(SOCKADDR *sa, int salen);
int               FormatAddress(SOCKADDR *sa, int salen, char *addrbuf, int addrbuflen);
int               ReverseLookup(SOCKADDR *sa, int salen, char *namebuf, int namebuflen);
struct addrinfo *ResolveAddress(char *addr, char *port, int af, int type, int proto);
 
#ifdef _cplusplus
}
#endif
 
#endif

//-----------------------resolve.cpp---------------------//

// 6
#include <winsock2.h>              // socket 标准头文件
#include <ws2tcpip.h>              // TCP/IP实现相关(6.1)
#include <strsafe.h>               // 提供安全的字符串操作(6.2)
#include <stdio.h>
#include <stdlib.h>
 
#include "resolve.h"

(6.1) 此头文件提供 getnameinfo,getaddrinfo函数。

(6.2) StringCchPrintf, StringCchCopy 具有相对于printf 和strcpy函数更多的缓冲区安全机制。

// 7
int PrintAddress(SOCKADDR *sa, int salen)
{
    char     host[NI_MAXHOST],
            serv[NI_MAXSERV];
    int      hostlen = NI_MAXHOST,
            servlen = NI_MAXSERV,
            rc;
 
    rc = getnameinfo(               // 提供协议无关的名字解析(7.1)
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
TCP/IP是指传输控制协议/互联网协议(Transmission Control Protocol/Internet Protocol)的简称。这是一组用于在互联网上进行数据传输的协议集合。 TCP/IP协议提供了一种可靠的、面向连接的通信方式,通过将数据分割成小的、以数据包形式传输的单元,确保数据的可靠传递。它还提供了一种基于IP地址的路由机制,使得数据可以在网络中正确地传递到目的地。 在Windows操作系统中,TCP/IP是内置的网络协议栈。这意味着Windows能够通过TCP/IP协议与其他计算机进行通信,实现网络连接和数据传输。 使用TCP/IP协议,在Windows系统上可以实现各种网络应用,例如Web浏览器、电子邮件客户端、文件传输等。通过TCP/IP协议,用户可以通过网络访问远程服务器上的资,进行文件共享、打印等操作。 为了使用TCP/IP协议,Windows操作系统会为每个网络接口分配一个IP地址。IP地址是用于识别网络上的设备和进行通信的核心元素。运行在Windows系统上的TCP/IP协议栈会根据IP地址将数据传输到正确的目标地址。 此外,Windows还提供了一些与TCP/IP协议相关的工具,如ping、tracert等,用于网络故障排除和网络性能测试。 总之,TCP/IP在Windows系统中是实现网络连接和数据传输的关键技术。通过TCP/IP协议,Windows用户可以在互联网上进行各种网络活动,并享受稳定、可靠的网络通信体验。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值