步子百科步子百科

icmp是什么协议(原生socket套接字实现ICMP协议)

版权声明:本文为作者原创文章,什协生s实现可以随意转载,议原但必须在明确位置表明出处!接字!协议!什协生s实现

前一篇文章讲了TCP协议,议原本篇文章我觉得有必要去实现一种协议,接字让我们更深刻的协议去理解协议内容,所以本篇文章选择ICMP(Internet Control Message Protocol)Internet控制报文协议,什协生s实现它是议原一种网络层协议,相信各位都使用过ping命令,接字监测主机和主机之间能够联通,协议而ping命令就是什协生s实现使用的ICMP协议,下面我们就用socket实现一个ping程序。议原

ping命令过程

1.Ping命令加上一个主机地址或者域名

2.等待对方主机应答。接字

3.统计发送接收次数,是否有丢包。

ICMP不能单独传输,它需要封装在IP数据报里。如下图所示:

发送ICMP数据报需要填充ICMP头部信息,头部+发送的数据部分组成一个ICMP报文。填充头部的意义是设置你想要的结果。ICMP头部占8个字节。类型一个字节,代码一个字节,校验和两个字节,标识符两个字节,序列号两个字节。类型和代码的组合可以表达不同的意义。这里我们会用到类型8代码0;表示的是ECHO请求。当对方主机返回类型为0时,表示ECHO应答。IP首部占20个字节下面给出ICMP头部和IP头部的定义。

ICMP报文类型

下面就是真枪实弹的干了,做这种协议类型的当让要属C/C++最合适了。既然ICMP需要IP数据报来搭载,那么我们就需要先定义IP协议头数据。

IP头部的定义

ICMP头部定义

下面我们就要填充ICMP头部信息

icmp_hdr->id = (USHORT)GetCurrentProcesId();这里的ID是唯一的标识符,他的作用是从应答中找到属于我发起的请求应答,是什么意思呢,一个网络地址可能同时有多个人去PING一台主机,那么主机返回的数据谁去接受呢?其实就是用ID来决定的,比如A、B两个用户,他们都ping同一台主机,A的ID = 1 B的ID = 2;那么主机返回的时候这个ID值是不会改变的,A判断ID == 1 就表示我返回我要接受的数据,同理B判断ID == 2,就是这个意思。

icmp_hdr->timestamp = GetTickCount();主要是用来记录请求应答的时间,当发送ECHO请求时记录发送时间,当接受到应答数据时,在用GetTickcount()- icmp_hdr->itmestamp这样就能得到请求应答需要多少时间了。

发送ICMP数据使用原始套接字,用sendto(···)函数,函数的接受可以查看MSDN关于本文的所有API函数都可以通过MSDN查看,多查看MSDN对我们提高英文能力,和学习能力都有很好的帮助,学习编程一定要多查看文档,遇到API先看文档,如果不是很明白在去百度,google这样会好一些。

下面是接受到ECHO应答后解析数据的过程:

下面是接受数据:

下面是发送请求数据

okay, 就讲到这里了,各位读者可以自己动手去试试,当然如果你们需要demo的也可以私信我。

欢迎关注我:「爱做饭的老谢」,老谢一直在努力...