我在网上找了很长时间。但是没有用。请帮助或试着给出一些想法如何实现这一目标。
我已经完成了程序的编写,今天当我测试ping环回地址时,在发送数据包后,recvfrom()函数收到了"first";报文(类型8),第二个recvfrom()收到响应报文(类型0)。
后来发现奇数次的类型值为8,偶数次的类型值为0。
我用Wireshark捕获的实际报文每次都有对应的响应报文,但是recvfrom()第一次接收到的是发送报文
// Send
if (sendto(sockfd, &sendicmp, ICMP_SIZE, 0, (struct sockaddr *) &to, sizeof(to)) == -1) {
printf("sendto() error n");
continue;
}
// Receive
struct timeval timeout = {3, 0};//3s
setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
if ((n = recvfrom(sockfd, buf, BUF_SIZE, 0, (struct sockaddr *) &from, &fromlen)) < 0) {
printf("Time out! n");
continue;
}
nreceived++;
if (unpack(buf, n) == -1) {
printf("unpack() error n");
}
在这里输入图像描述因为类型值不是0,所以我让输出不是发送给我的ICMP数据包
ICMP类型8的控制消息是一个回显请求。类型0是回显应答。因此,听起来您的程序除了接收对这些请求的回复之外,还接收自己的请求。如果您成功ping到一个环回地址,这是很自然的,因为环回就是这样工作的。
对于TCP和UDP来说,这不是一个问题,因为这些协议在普通IP上提供了端口的概念,以区分通过相同地址通信的不同应用程序。ICMP没有这个功能,所以接收ICMP消息的进程有责任执行自己的消息过滤。特别是ping程序可能会忽略传入的ICMP消息,而不是回显应答(类型0)。它可能进一步使用ICMP报头的后四个字节来区分对它自己的回显请求的应答和对同时运行的其他程序的应答。