【问题标题】:Ping program implementation in C about recvfrom() doubtsC 中 Ping 程序实现关于 recvfrom() 的疑惑
【发布时间】:2021-12-09 19:27:38
【问题描述】:

我在网上搜索了很长时间。但是没有用。请帮助或尝试提供一些想法如何实现这一目标。

程序写完了,今天测试ping环回地址,发送数据包后,recvfrom()函数收到“第一个”数据包(类型8),第二个recvfrom()收到响应数据包(类型 0)。

后来发现奇数次的type值为8,偶数次的type值为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");
        }

enter image description here Since the type value is not 0, I let the output is not the ICMP packet sent to me

【问题讨论】:

标签: c linux sockets ping icmp


【解决方案1】:

ICMP 8 类控制消息是一个回显请求。类型 0 是回显回复。因此,听起来您的程序除了收到对这些请求的回复外,还收到了自己的请求。如果您成功 ping 回环地址,这很自然,因为环回就是这样工作的。

这对于 TCP 和 UDP 来说不是什么大问题,因为这些协议在顶级普通 ​​IP 上提供了端口概念,以区分通过相同地址进行通信的不同应用程序。 ICMP 没有这个功能,因此接收 ICMP 消息的进程负责执行自己的消息过滤。特别是 ping 程序可能会忽略传入的 ICMP 消息,而不是回显回复(类型 0)。它还可能使用 ICMP 标头的后四个八位字节来区分对自己的回显请求的回复和对同时运行的其他程序的回复。

【讨论】:

    猜你喜欢
    • 2016-05-30
    • 2013-01-07
    • 2011-11-27
    • 1970-01-01
    • 1970-01-01
    • 2016-02-08
    • 2022-01-21
    • 2014-11-29
    • 2014-08-17
    相关资源
    最近更新 更多