道德三皇五帝,功名夏后商周.英雄五霸闹春秋,顷刻兴亡过手.青史几行名姓,北邙无数荒丘.前人田地后人收,说甚龙争虎斗。
ICMP报文是一种面向无连接的协议,用于传输出错报告控制信息。它是一个非常重要的协议,ICMP提供一致易懂的出错报告信息。发送的出错报文返回到发送原数据的设备,因为只有发送设备才是出错报文的逻辑接受者。发送设备随后可根据ICMP报文确定发生错误的类型,并确定如何才能更好地重发失败的数据包。但是ICMP唯一的功能是报告问题而不是纠正错误,纠正错误的任务由发送方完成 。
ICMP报文对于我来说最大的意义是侦测主机是否存在。这一点要命。
windows大名鼎鼎的PING程序就是ICMP协议,因此就ICMP的SOCKET实现记述一二,
第一部分:实现
ICMP的实现依赖于SOCKET,那么SOCKET是这样做的流程:
PING 发送程序
1、socket(AF_INET, SOCK_RAW, IP_PROTO_ICMP)
建立SOCKET,ICMP协议
2、setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout))
配置SOCKET的接受超时时间,我配置的为10S
3、 iecho = rt_malloc(ping_size);
构建PING数据,数据长度为32字节+icmp_echo_hdr的头
4、 /* fill the additional data buffer with some data */
for(i = 0; i < data_len; i++)
{
((char*)iecho)[sizeof(struct icmp_echo_hdr) + i] = (char)i;
}
iecho->chksum = inet_chksum(iecho, len);
填充数据
5、sendto(s, iecho, ping_size, 0, (struct sockaddr*)&to, sizeof(to));
发送数据
6、 free(iecho);释放内存
到此PING程序的发送完成。
PING 接收程序
1、recvfrom(s, buf, sizeof(buf), 0,(struct sockaddr*)&from, (socklen_t*)&fromlen)
阻塞于ICMP的socket上,等待回应
2、 addr = (struct _ip_addr *)&(from.sin_addr);
如果收到回应那么输出回应的IP地址
3、printf("ping: timeout\n");
如果没有收到回应,10S后会返回系统一个 超时
当然数据已经被存入BUFF中,想用随时取出即可。我目前是丢掉的。
第二部分:测试
程序完成后的测试结果如下:

可见ICMP报文的包确实是正常发出来了。
IP地址是192.168.0.105是板子
IP地址是192.168.0.100是电脑。
debug时也可以正常收到电脑的回复数据。
这证明此流程程序可用!
最后socket的收发程序目前采用的都是堵塞方式实现,也就是说底层和上层接口之间用邮箱来通信。有数据立马推送,所以这个也是应用程序编写的关键之所在。如果不能及时的收取那么很可能box溢出,那就不是溢出那么简单的事情了。所以只能是单线程处理,绝对禁止多线程。前人的经验血的教训!
于日照比特电子
老伟
|