一个进程中需要检测多台主机是否正常工作,采用了ICMP检测的方式,每个主机一个线程,定时PING对应主机是否存活。最后发现当有主机down机的情况下,依然能收到ICMP的回应报文。
这个问题看起来很奇怪,其实了解PING的实现原理就会觉得出现这样的问题很正常。
首先ICMP是基于RAW套接字的,RAW套接字只匹配协议,并不按流匹配,也就是说一个或者多个进程采用RAW方式监听同样协议的socket时,都能收到相同的报文。多个ping进程之所以不出问题,是因为PING将ICMP报文中的icmp_id设置为对应的进程号,进一步通过进程号来区分是否属于自己的报文。最主要的原因是用户态已经去掉了ICMP的报文头,无法看到原地址和目的地址了,所以只能通过ICMP报文的内容来区分。
进而就可以明白为什么多线程情况下检测多台主句会出问题了,因为进程号都一样,所以大家都能收到相同的回应报文,这种情况下只需要修改下icmp协议中icmp_id为自己定义的值就行了。
在TCP和UDP协议情况下,不会用到RAW属性去创建套接字,所以不会有以上 问题。
socket() creates an endpoint for communication and returns a descriptor.
The domain parameter specifies a communication domain; this selects the protocol family which will be used for communication. These fa