我在网上搜索了很长时间。但没用。请帮助或尝试给一些想法如何实现这一点。
我已经编写完程序,今天当我测试ping回环地址时,在发送数据包之后,函数recvfrom()接收到“第一个”数据包(类型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");
}发布于 2021-10-23 17:36:55
ICMP类型8控制消息是回送请求。类型0是回显答复。因此,听起来除了对这些请求的答复之外,您的程序还收到了自己的请求。如果您成功地敲击回送地址,这是很自然的,因为这就是回送的工作方式。
对于TCP和UDP来说,这不是什么问题,因为这些协议提供了一个简单IP上端口的概念,以区分通过相同地址通信的不同应用程序。ICMP没有这种功能,因此接收ICMP消息的进程有责任执行自己的消息过滤。尤其是ping程序可能会忽略传入的ICMP消息,而不是回显答复(类型0)。它还可以使用ICMP头的第二个四位数来区分对自己回显请求的答复和对同时运行的其他程序的答复。
https://stackoverflow.com/questions/69688951
复制相似问题