< 返回版块

leowei1234567 发表于 2023-03-03 10:13

单独运行此程序,预期是发送失败,但现实的日志是成功发送和失败交替出现

日志如下

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);
    }
}

评论区

写评论
hax10 2023-03-03 14:40

是的, send必须跟固定的远端端口绑定。虽然UDP connect()不会像TCP链接那样跟远端进行握手,但是每次发的消息都通往固定的远方端口,这样也方便向你转发远方发的错误消息。反而send_to不需要connect()且每次发消息时能换一个目的地,因为多个来源的错误消息不方便在同一个地方处理所以它就不报错,毕竟UDP本来不提供可靠性保障。

--
👇
leowei1234567: 对比了一下sendto,也试了一下go的程序,确实是socket实现的原因,sendto不会得到ICMP报错

作者 leowei1234567 2023-03-03 14:06

对比了一下sendto,也试了一下go的程序,确实是socket实现的原因,sendto不会得到ICMP报错

--
👇
hax10: 轮流成功是因为tokio能正常将数据交给操作系统发出去,但是因为没有服务器在9090号端口接收你的请求,所以操作系统通过ICMP消息报错了。你再次向同一端口发消息时就能看见这错误,但是你依然还能正常使用这个socket对象。

hax10 2023-03-03 11:52

轮流成功是因为tokio能正常将数据交给操作系统发出去,但是因为没有服务器在9090号端口接收你的请求,所以操作系统通过ICMP消息报错了。你再次向同一端口发消息时就能看见这错误,但是你依然还能正常使用这个socket对象。

作者 leowei1234567 2023-03-03 11:15

看上去这是一个socket实现的机制

1 共 4 条评论, 1 页