问题描述
我有一个UDP服务器,它侦听所有IPv4地址,即INADDR_ANY或0.0.0.0。对于从客户端收到的每个数据包,它均应以接收该数据包的确切网络接口的IP地址作为响应。从概念上讲,它应该将数据包的源地址放入数据包的有效负载中。
使用sendto()
时,如何知道哪个源地址用于将数据包发送到特定的目标地址?我是否需要手动枚举所有网络接口,将网络前缀(或与此相关的子网掩码的IPv4地址)与目标地址进行匹配?如果是这样,怎么办?我会对涉及Boost.Asio的跨平台解决方案感兴趣,但如果不可能,则需要使用Winsock。将来,我可能也需要Linux的解决方案。
解决方法
对于从客户端收到的每个数据包,它都应以接收到该数据包的确切网络接口的IP地址作为响应。
通常不需要手动处理。如果您只是sendto()
将数据包发送到recvfrom()
报告的发件人的IP /端口,则操作系统将根据哪个接口具有到该发件人的可用路由来为您路由该数据包。
使用
sendto()
时,如何知道哪个源地址将数据包发送到特定的目标地址?
您可以使用setsockopt()
在监听的UDP套接字上启用IP_PKTINFO
选项,然后使用WSARecvMsg()
(Windows)或recvmsg()
(Linux)代替{{ 1}}。这样,您就可以访问recvfrom()
结构,该结构告诉您接收到的数据包发送到的目标IP,以及实际接收到该数据的接口。