如何从udp端点获取*my*ip

NoS*_*tAl 7 c++ boost boost-asio

Boost.Asio udp::endpoint有一个远程地址的成员.因为我正在监听多个接口(如下所示):

udp_socket(io_service, udp::endpoint(udp::v4(), port))
Run Code Online (Sandbox Code Playgroud)

在我的处理程序中,我不知道哪个网络接口收到了数据包.

如果没有遍历网络接口并在每个接口上寻找端点地址和我的IP之间的相似性,我可以从我收到消息的接口获取IP吗?

Tan*_*ury 7

否.Boost.Asio不会暴露识别数据报目标地址的能力.

socket::aync_receive_from()socket::receive_from()操作执行中的本地套接字操作boost::asio::detail::socket_ops::recvfrom().在Windows上,WSARecvFrom()无法从协议堆栈中提取较低层信息.在Linux上,IP_PKTINFO套接字选项可以提供给面向数据报的套接字,从而recvfrom()能够msghdr.msg_control使用辅助信息填充缓冲区,例如接收数据包的接口索引和数据包标头中的目标地址.但是,Boost.Asio 实现不使用该msg_control字段:

msghdr msg = msghdr();
init_msghdr_msg_name(msg.msg_name, addr);
msg.msg_namelen = static_cast<int>(*addrlen);
msg.msg_iov = bufs;
msg.msg_iovlen = static_cast<int>(count);
signed_size_type result = error_wrapper(::recvmsg(s, &msg, flags), ec);
Run Code Online (Sandbox Code Playgroud)

回答所示,人们可以:

  • 使用较低级别的系统调用.(即IP_PKTINFOrecvfrom())
  • 将套接字显式绑定到每个接口而不是INADDR_ANY,导致socket::local_endpoint()返回特定接口.完成处理程序需要一些方法来获取调用操作的套接字上的本地端点,例如通过引用传递给套接字或其本地端点boost::bind().

  • 不,路由发生在内核级别.内核充当路由器,使用出站数据的目标地址来确定数据的最佳路由,例如哪个接口将实际写入数据.因此,可以将数据发送到已绑定到`eth0`上的IP的套接字,但内核确定到数据目的地的最佳路由实际上是通过`eth1`,因此数据从`eth1`发送源地址为"eth0". (2认同)