单独运行此程序,预期是发送失败,但现实的日志是成功发送和失败交替出现
日志如下
I got ticker
Ok(100)
I got ticker
Err(Os { code: 111, kind: ConnectionRefused, message: "Connection refused" })
I got ticker
Ok(100)
I got ticker
Err(Os { code: 111, kind: ConnectionRefused, message: "Connection refused" })
code:
use prost::Message as prostMessage;
use std::time::Duration;
use std::{io, net::SocketAddr, sync::Arc};
use tip_proto::pb::communication::{CommunicationData, HandoverData, Scenes};
use tokio::time;
use tokio::{net::UdpSocket, sync::mpsc};
#[tokio::main]
async fn main() -> io::Result<()> {
let sock = UdpSocket::bind("0.0.0.0:9091").await?;
let remote_addr = "127.0.0.1:9090";
sock.connect(remote_addr).await?;
let r = Arc::new(sock);
let s = r.clone();
tokio::spawn(async move {
let buf = [1; 100];
let mut ticker = time::interval(Duration::from_secs(5));
loop {
ticker.tick().await;
// do_something().await;
println!("I got ticker");
let len = s.send(&buf[..]).await;
println!("{:?}", len);
}
});
let mut buf = [0; 1024];
loop {
let len = r.recv(&mut buf).await?;
println!("{:?} bytes received", len);
println!("buf is {:?}", &buf[..len]);
let mut communication_data: CommunicationData =
CommunicationData::decode(&buf[..len]).unwrap();
println!("{:?}", &communication_data);
}
}
1
共 4 条评论, 1 页
评论区
写评论是的, send必须跟固定的远端端口绑定。虽然UDP connect()不会像TCP链接那样跟远端进行握手,但是每次发的消息都通往固定的远方端口,这样也方便向你转发远方发的错误消息。反而send_to不需要connect()且每次发消息时能换一个目的地,因为多个来源的错误消息不方便在同一个地方处理所以它就不报错,毕竟UDP本来不提供可靠性保障。
--
👇
leowei1234567: 对比了一下sendto,也试了一下go的程序,确实是socket实现的原因,sendto不会得到ICMP报错
对比了一下sendto,也试了一下go的程序,确实是socket实现的原因,sendto不会得到ICMP报错
--
👇
hax10: 轮流成功是因为tokio能正常将数据交给操作系统发出去,但是因为没有服务器在9090号端口接收你的请求,所以操作系统通过ICMP消息报错了。你再次向同一端口发消息时就能看见这错误,但是你依然还能正常使用这个socket对象。
轮流成功是因为tokio能正常将数据交给操作系统发出去,但是因为没有服务器在9090号端口接收你的请求,所以操作系统通过ICMP消息报错了。你再次向同一端口发消息时就能看见这错误,但是你依然还能正常使用这个socket对象。
看上去这是一个socket实现的机制