C++ 如何从udp端点获取*我的*ip
Boost.Asio的C++ 如何从udp端点获取*我的*ip,c++,boost,boost-asio,C++,Boost,Boost Asio,Boost.Asio的udp::endpoint有一个成员是远程地址。因为我正在监听多个接口(如下所示): 在我的处理程序中,我不知道哪个网络接口收到了数据包 如果不在网络接口上迭代,也不在每个接口上查找端点地址和我的IP之间的相似性,我可以获取我从中获取消息的接口的IP吗?据我所知,您有不同的选择。如果其中一个收到一条消息,您希望知道该套接字的本地ip地址/套接字使用的接口 因此,如果socket是接收消息的套接字,那么您应该能够通过 socket.local_endpoint().addre
udp::endpoint
有一个成员是远程地址。因为我正在监听多个接口(如下所示):
在我的处理程序中,我不知道哪个网络接口收到了数据包
如果不在网络接口上迭代,也不在每个接口上查找端点地址和我的IP之间的相似性,我可以获取我从中获取消息的接口的IP吗?据我所知,您有不同的选择。如果其中一个收到一条消息,您希望知道该套接字的本地ip地址/套接字使用的接口 因此,如果
socket
是接收消息的套接字,那么您应该能够通过
socket.local_endpoint().address()
请参阅boost手册中的和。我认为您应该明确指定地址,而不仅仅是协议
udp_socket(io_service, udp::endpoint(boost::asio::ip::address::from_string(""), port))
因此,您可以使用
udp\u socket.local\u endpoint()
和操作在中执行本机套接字操作。在Windows上,无法从协议堆栈中提取下层信息。在Linux上,可以向面向数据报的套接字提供套接字选项,以便使用辅助信息填充msghdr.msg_control
缓冲区,例如接收数据包的接口索引和数据包头中的目标地址。但是,Boost.Asio不使用msg\u控件
字段:
msghdr msg=msghdr();
初始名称(msg.msg\u名称,地址);
msg.msg_namelen=静态播放(*addrlen);
msg.msg_iov=bufs;
msg.msg_iovlen=静态(计数);
带符号的大小类型结果=错误包装(::recvmsg(s,&msg,flags),ec);
如答覆所述,我们可以:
- 使用较低级别的系统调用。(即
IP_PKTINFO
和recvfrom()
)
- 显式地将套接字绑定到每个接口,而不是
INADDR\u ANY
,从而导致返回特定接口。完成处理程序需要某种方法来获取调用操作的套接字上的本地端点,例如通过boost::bind()
传递对套接字或其本地端点的引用
不,我有一个插座,它只监听任何地址。。。像这样:udp_套接字(io_服务,udp::endpoint(udp::v4(),port))/*…*/start_receive(){udp_socket.async_receive_from(boost::asio::buffer(m_recv_buffer),remote_endpoint,@nosenseal啊,好的。但是调用local_endpoint()
在处理程序中应该可以工作,不是吗?不,我刚刚得到0.0.0.0好,奇怪。我稍后会在我的机器上检查它。确保像这样构造套接字:udp_套接字(io_服务,udp::endpoint(udp::v4(),port)),但有趣的是,当我使用endpoint时,更改它的端口(它使用diff port进行侦听)发送回复发送方得到回复…这是否意味着所有接口上都有boost回复?我在处理程序中是这样发送的:request\u source.port(reply\u port);boost::asio::ip::udp::socket udp_socket(service,boost::asio::ip::udp::endpoint(boost::asio::ip::address(),0));udp_socket.send_to(boost::asio::buffer(reply,reply.size()),请求_源);否,路由发生在内核级别。内核用作路由器,使用出站数据的目标地址来确定数据的最佳路由,例如哪个接口将实际写入数据。因此,可以将数据发送到绑定到eth0
上的IP的套接字,但内核决定nes到数据目的地的最佳路径实际上是通过eth1
,因此数据从eth1
发送,源地址为eth0
。
udp_socket(io_service, udp::endpoint(boost::asio::ip::address::from_string(""), port))