当前位置: 首页 > 知识库问答 >
问题:

C-recvfrom的结果意外

宓博实
2023-03-14
$> ./my_ping qwant.com
IPv4: hdr-size=20 pkt-size=56 protocol=1 TTL=254 src=10.0.2.2 dest=172.17.0.2
$> ping qwant.com
PING qwant.com (194.187.168.99): 48 data bytes
56 bytes from 194.187.168.99: icmp_seq=0 ttl=61 time=101.742 ms
struct addrinfo hints;
struct addrinfo *a_info;

bzero(&hints, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_protocol = 0;
hints.ai_flags = AI_ADDRCONFIG;

getaddrinfo(host, NULL, &hints, &a_info)
sock = socket(PF_INET, SOCK_RAW, IPPROTO_ICMP);
setsockopt(sock, SOL_IP, IP_TTL, (void *)&val, sizeof(val);
size_t                  i;
t_ping                  pack;
int                     count = 1;
struct iphdr            buff;

while (TRUE)
{
    bzero(&pack, sizeof(pack));
    pack.head.type = 8;
    pack.head.code = getpid();
    pack.id = count++;

    while (i < 15)
    {
        pack.seq[i] = i + '0';
        i++;
    }
    pack.seq[i] = 0;
    pack.head.chk = checksum(&pack, sizeof(pack));
    ft_bzero((void *)&buff, sizeof(buff));

    if (sendto(sock, &pack, sizeof(pack), 0, a_info->ai_addr, a_info->ai_addrlen) < 0)
        perror("sendto");
    if (recvfrom(sock, (void *)&buff, sizeof(buff), 0, a_info->ai_addr, &a_info->ai_addrlen) < 0)
        perror("recvfrom");

    display((void *)&buff);
    sleep(1);
}
struct iphdr    *ip = buff;
char src[INET6_ADDRSTRLEN];
char dest[INET6_ADDRSTRLEN];

inet_ntop( AF_INET, (void *)&ip->saddr, src, sizeof(src) );
inet_ntop( AF_INET, (void *)&ip->daddr, dest, sizeof(dest) );


printf("IPv%d: hdr-size=%d pkt-size=%d protocol=%d TTL=%d src=%s dest=%s\n",
    ip->version,
    ip->ihl*4,
    ntohs(ip->tot_len),
    ip->protocol,
    ip->ttl,
    src,
    dest);

在我看来,我的缓冲区包含关于最后一个数据包步骤(路由器->my home)的信息,这些信息解释了为什么TTL值是254以及为什么我用Traceroute找到了相同的两个IP:

$>traceroute qwant.com
traceroute to qwant.com(194.187.168.99),30跳最大,60字节数据包
172.17.0.1(172.17.0.1)0.026 ms 0.011 ms 0.010 ms
10.0.2.2(10.0.2.2)0.149 ms 0.160 ms 0.156 ms
[...]
194.187.168.99(194.187.168.99)147.634 ms 147.506 ms 147.540 ms

为什么收到的信息不是关于我的服务器目标的?我怎样才能收到这些信息?

共有1个答案

申屠乐池
2023-03-14

Internet分配号码管理局(IANA)为专用网络保留了以下三块IP地址空间:

          10.0.0.0        -   10.255.255.255
          172.16.0.0      -   172.31.255.255
          192.168.0.0     -   192.168.255.255

172.17.0.2是专用网络的地址。我猜你的机器在这个网络里,服务器也在里面。

getaddrinfo()可以返回多个地址。试着检查一下所有的回复,检查一下你是否也得到了互联网地址。

for (rp = result; rp != NULL; rp = rp->ai_next) {
    sfd = socket(rp->ai_family, rp->ai_socktype,
            rp->ai_protocol);
    if (sfd == -1)
        continue;

   if (bind(sfd, rp->ai_addr, rp->ai_addrlen) == 0)
        break;                  /* Success */

   close(sfd);
}
 类似资料:
  • 我正在编写udp服务器/客户端应用程序,其中服务器发送数据,客户端接收数据。当数据包丢失时,客户端应该向服务器发送nack。我将套接字设置为O_NONBLOCK,这样我就可以注意到客户端是否没有收到数据包 我的问题是,若服务器并没有开始发送数据包,那个么客户端的行为就是数据包丢失,并且开始向服务器发送nack。(没有可用数据时recvfrom失败)我需要一些建议,如果服务器没有开始发送数据包,如果

  • 问题内容: 给定一个变量,该变量包含巴黎时区的日期时间2000-01-01 00:01(冬季afaik中为UTC + 2): 我希望转换为UTC会导致日期时间为1999-12-31 22:01,但是却得到了: 我想念什么? 谢谢 问题答案: 不幸的是 ,在许多时区使用标准构造函数的参数“不起作用” 。 但是对于没有夏令时转换的时区来说是安全的,例如UTC: 您会注意到: “ LMT + 0:09:

  • 我有以下代码: 为什么它会打印Java流?

  • 我有以下代码,它将标记字符串以创建对象列表: 我预期的输出是 1#、#Jon#、#176 2#、#Jack#、#200 3#、#Jimmy#、#160 如果我把内部分界线更改为类似的东西,它会正常工作为什么会发生这种行为?

  • 我使用了以下映射:我修改了英语分析器来使用ngram分析器,如下所示,这样我应该能够在以下情况下进行搜索:1]部分搜索和特殊字符搜索2]以获得语言分析器的优势 将我的数据索引如下:

  • recvfrom(经socket接收数据) 相关函数 recv,recvmsg,send,sendto,socket 表头文件 #include<sys/types.h> #include<sys/socket.h> 定义函数 int recvfrom(int s,void *buf,int len,unsigned int flags ,struct sockaddr *from ,int *f