【发布时间】:2017-02-27 10:09:58
【问题描述】:
我的目标是在广播地址范围ff05:e671:2015::1 上监听 udp 数据报。收到后,恢复具体的服务器ip。
目前,我正在接收有效的数据包。但是,当我检查源地址时,这里有几个输出:
fd01:e671:2015:5c01::
fd01:e671:2015:d101::
这是我的代码的相关部分:
std::array<char, 1024> _buff;
sockaddr a {};
socklen_t s = sizeof( a );
auto bytes = recvfrom( _fd, _buff.data(), _buff.size(), MSG_DONTWAIT | MSG_TRUNC, &a, &s );
...
// reuse the buffer
sockaddr_in6 *sin = reinterpret_cast<sockaddr_in6*>( &a );
inet_ntop( AF_INET6, &sin->sin6_addr, _buff.data(), INET6_ADDRSTRLEN );
最后,这是tcpdump | grep fd01:e671:2015:5c01的一些输出:
10:07:31.452905 IP6 fd01:e671:2015:5c01:203:2dff:fe34:d598.20001 > ff05:e671:2015:5c01:203:2dff:fe34:d598.20001: UDP, length 120
10:07:31.453122 IP6 fd01:e671:2015:5c01:203:2dff:fe34:d598.20001 > ff05:e671:2015:5c01:203:2dff:fe34:d598.20001: UDP, length 161
10:07:31.453128 IP6 fd01:e671:2015:5c01:203:2dff:fe34:d598.20001 > ff05:e671:2015:5c01:203:2dff:fe34:d598.20001: UDP, length 202
10:07:31.453130 IP6 fd01:e671:2015:5c01:203:2dff:fe34:d598.20001 > ff05:e671:2015:5c01:203:2dff:fe34:d598.20001: UDP, length 80
10:07:31.453131 IP6 fd01:e671:2015:5c01:203:2dff:fe34:d598.20001 > ff05:e671:2015:5c01:203:2dff:fe34:d598.20001: UDP, length 121
10:07:31.453133 IP6 fd01:e671:2015:5c01:203:2dff:fe34:d598.20001 > ff05:e671:2015:5c01:203:2dff:fe34:d598.20001: UDP, length 162
如何获取完整具体的数据报源ip?
【问题讨论】:
-
您期望的输出是什么?
_buff是什么?_buff.size()返回什么?在recvfrom调用和inet_ntop调用之间会发生什么(尤其是a)?您是否检查过该地址是一个 IPv6 地址?最后,如何打印输出?请尝试创建Minimal, Complete, and Verifiable Example 并展示给我们。 -
@Someprogrammerdude 我期待像
fd01:e671:2015:5c01:203:2dff:fe34:d598这样的东西。另外,很明显,我希望用 _buff 编写的 boh C 函数放置一个分隔符\0。 -
如果
sizeof (sockaddr)是 16 而sizeof(sockaddr_in6)是 28,它在我的平台上怎么办。完整地址如何适合a? -
@DavidSchwartz 这似乎解决了问题!我想了好几个小时!文档明确要求 sockaddr 参数:
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen);。你能发布一个简短的答案吗?