用C 语言实现 Ping
来源:互联网 发布:java 搜索算法 编辑:程序博客网 时间:2024/05/21 12:41
一.套接字
int socket(int domain,int type,int protocol); 参数domain确定通信特性,它有4个域分别为 AF_INET IPV4英特网域 AF_INET6 IPV6因特网域 AF_UNIX UNIX 域 AF_UPSPEC 未指定 参数 type 确定套接字类型,进一步确定通信特性 SOCK_DGRAW 固定长度、无连接、不可靠的包文传递 SOCK_RAW IP 协议数据接口 SOCK_SEQPACKET 固定长度的、有序的、可靠的、面向连接的报文传递 SOCK_STREAM 有序的、可靠、双向的、面向连接的字节流 参数 protocol 通常是0,表示为给定的域和套接字选择默认 协议。AF_INT域SOCK_STREAM默认为传输控制协议 TCP, AF_INT域套接字类型 SOCK_DGRAM 的默认协议是 UDP。 下面为英特网套接字定义的协议: IPPROTO_IP, IPPROTO_IPV6, IPPROTO_ICMP IPPROTO_RAW, IPPROTO_TCP, IPPROTO_UDP 返回值为套接字描述符,本质为一个文化描述符
SOCK_RAW和IPPROTO_ICMP
SOCK_RAW套接字提供一个数据报接口,用于直接访问下面的网络层因为其绕过了传输协议(如 TCP和 UDP),所以我们必须自己构造协议头部。注意当我们创建这个套接字的时候我们必须有超级用户特权。因此实现 Ping 我们先来定义 ICMP 头部 struct ICMPHEAD{ u_int8_t type; u_int8_t code; u_int16_t checkSum; u_int16_t id; u_int16_t seq;};我们实现 Ping 必须发送回显请求数据包,其类型代码为8,代码报文为0.回显请求数据包类型为0,代码报文为0.id 给数据包一个标示用于判断是否为我们所发送的数据包。checkSum为检验和字段,包括数据在内的整个 ICMP 报文检验和。ushort GenerationChecksum(ushort*pBuf,int iSize){unsigned long cksum = 0;while(iSize > 1){ cksum+=*pBuf++; iSize-=sizeof(ushort);}if(iSize) cksum+=*pBuf++;cksum = (cksum>>16)+(cksum&0xffff);cksum += (cksum>>16);return (ushort)(~cksum);}定义完我们的数据包之后,剩下就是定义一个目的地址。struct sockaddr_in {__uint8_t sin_len;sa_family_t sin_family;in_port_t sin_port;struct in_addr sin_addr;char sin_zero[8];};sin_family为地址族sin_addr为目的地址sin_port为端口号struct sockaddr_in destSocketAddr;destSocketAddr.sin_family = AF_INET;destSocketAddr.sin_addr.s_addr = ulDestIP;destSocketAddr.sin_port = htons(0);memset(destSocketAddr.sin_zero, 0, sizeof(destSocketAddr.sin_zero));
发送ICMP
ssize_t sendto(int, const void *, size_t,int, const struct sockaddr *, socklen_t)第一个参数为套接字描述符。第二个参数为 ICMP 数据包第三个参数为 ICMP 的大小第四个参数为目的地址,为使不同的地址格式传入这个函数,因此必须强转为 sockaddr。第五个参数为目的地址大小
接受回显应答报文
ssize_t recvfrom(int, void *, size_t, int,struct sockaddr * __restrict,socklen_t * __restrict)第一个参数为套接字描述符第二个参数接受数据缓存区的首地址第三个参数为数据缓存区大小第四个参数为接受发送数据的地址信息第五个参数为第四个参数的大小接受的数据为 IP 数据报,因此我们可以定义一个结构体来方便我们操作 IP 数据报ip 头结构体typedef struct tag_iphdr { u_int8_t iphVerLen;//注意这个包括版本和首部长度 u_int8_t ipTOS; ushort ipLength; ushort ipID; ushort ipFlags; u_int8_t ipTTL; u_int8_t ipProtacol; ushort ipChecksum; int ipSource; int ipDestination;} IPHDR;利用 ip 头部中的首部长度信息获得我们需要的回显应答数据包。解析回显应答数据包我们的 Ping就完成了。
DEMO在这里
0 0
- 用C 语言实现 Ping
- c语言实现ping
- 用C语言实现Ping程序功能
- 用C语言实现Ping程序功能
- 用C语言实现ping程序
- 用C语言实现Ping程序功能
- 用C语言实现Ping程序功能
- 用C语言实现Ping程序功能
- 用C语言实现Ping程序功能
- 用C语言实现Ping程序功能
- 用C语言实现Ping程序功能
- 用C语言实现Ping程序功能
- 用C语言实现Ping程序功能
- 用C语言实现Ping程序功能
- 用C语言实现Ping程序功能
- 用C语言实现Ping程序功能
- 用C语言实现Ping程序功能
- 用C语言实现Ping程序功能
- Android重拾设计模式系列——抽象工厂模式
- android悬浮窗口
- 自定义组合布局
- popwindow中放gridview带有item依次显示动画效果
- Codeforces 723A-The New Year: Meeting Friends
- 用C 语言实现 Ping
- Bootstrap-段落和文本
- [计算机网络笔记]第一部分——概述
- 细说@synchronized和dispatch_once[细读][笔记]
- Tr1 Function
- Spring 自定义标签
- 剑指Offer面试题33
- Android自定义iOS风格Dialog
- 关于数据结构中的栈的基本算法