rust - 如何“连接”一个 UDP 套接字并让操作系统选择端口和地址
问题描述
我想向服务器发送一个 UDP 查询并接收它的响应。在 C 中是:调用socket
then connect
then write
thenread
。操作系统负责选择合适的本地 IP 地址和要使用的端口。
我正在尝试在 Rust 中做同样的事情。但是我找不到UdpSocket
自己指定地址和端口的方法。我能做的最接近的是:
fn main() {
use std::net::{Ipv4Addr, UdpSocket};
let socket = UdpSocket::bind((Ipv4Addr::UNSPECIFIED, 12345)).unwrap();
socket.connect("1.1.1.1:53").unwrap();
socket.send(b"\x12\x34\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\
\x07example\x03com\x00\
\x00\x01\x00\x01").unwrap();
let mut buffer = [0; 512];
let len = socket.recv(&mut buffer).unwrap();
for b in &buffer[0..len] {
print!("{:02x} ", b);
}
println!("");
}
这可行,但与 C 版本相比有两个缺点。
如果我指定一个已经在使用的本地端口,它可能会失败,
套接字侦听所有可用地址,而 C 版本仅侦听“合适的”地址。这对于 UDP 避免响应欺骗很重要。
比如我查询127.0.0.1,那么C版会自动绑定到127.0.0.1这个地址。互联网将无法欺骗我的查询答案。另外,如果我有两个网络接口,一个连接到互联网,一个连接到我的本地网络,IP 为 192.168.0.1,我可以查询本地网络上的解析器,如 172.16.17.18。C 版本将绑定到地址 192.168.0.1,我确信答案不是来自互联网。
我将如何最好地做与 C 版本相同的操作?
编辑:解释关于寻找“合适”地址的第二点。
解决方案
这并不明显,但是如果将套接字绑定到(UNSPECIFIED, 0)
,那么当您连接到远程地址时,本地地址将设置为适当的接口地址。(端口0
表示自动分配端口,就像 C 中的未绑定套接字一样。)您可以通过local_addr()
在连接成功后调用套接字来确认这一点。
我为 POSIX 的复杂性道歉。:-)
推荐阅读
- xml - 文本视图的问题
- python - 如何在 python k8s 客户端中以 root 身份运行“connect_get_namespaced_pod_exec”
- c# - Swashbuckle.AspNetCore.SwaggerGen v5 不发送标头
- r - R语言函数工厂:如何保证安全?
- javascript - 创建 BulkDelete 命令 | 不和谐.JS
- shell - 通过 jumphost 的 SSH socks 代理
- django - django rest框架不显示响应数据
- mysql - 如何将其转换为 DATETIME SQL?
- python - 没有收到回波警告导致我的 HR-SC04 超声波模块(距离传感器)导致输出错误
- tensorflow - 我在自定义数据集上训练了 ssd mobilenet v1,在 jetson 中运行的尺寸减小问题