2 个不稳定版本
0.2.0 | 2020 年 12 月 28 日 |
---|---|
0.1.2 | 2018 年 4 月 28 日 |
#21 在 #udp-server
10KB
udp_sas_mio
Rust 中 UDP mio 套接字源地址选择
此软件包为 mio::net::UdpSocket
提供了一个扩展特质,支持对传出 UDP 数据包进行源地址选择。这对于实现绑定多个网络接口的 UDP 服务器非常有用。
实现依赖于软件包 udp_sas
lib.rs
:
此软件包为 mio::net::UdpSocket
提供了一个扩展特质,支持对传出 UDP 数据包进行源地址选择。这对于实现绑定多个网络接口的 UDP 服务器非常有用。
实现依赖于套接字选项 IP_PKTINFO
(IPv4)和 IPV6_RECVPKTINFO
(IPv6)。
extern crate mio;
extern crate udp_sas_mio;
use std::net::SocketAddr;
use std::time::Duration;
use mio::{Events,Interest,Poll,Token};
use mio::net::UdpSocket;
use udp_sas_mio::UdpSas;
fn main() {
demo().unwrap();
}
fn demo() -> std::io::Result<()>
{
let mut buf = [0u8;128];
// Create the server socket and bind it to 0.0.0.0:30012
//
// Note: we will use 127.0.0.23 as source/destination address
// for our datagrams (to demonstrate the crate features)
//
let mut srv = UdpSocket::bind_sas("0.0.0.0:30012".parse::<SocketAddr>().unwrap())?;
let srv_addr : SocketAddr = "127.0.0.23:30012".parse().unwrap();
// Create the client socket and bind it to an anonymous port
//
// Note: we will use 127.0.0.45 as source/destination address
// for our datagrams (to demonstrate the crate features)
//
let mut cli = UdpSocket::bind_sas("0.0.0.0:0".parse::<SocketAddr>().unwrap())?;
let cli_addr = SocketAddr::new(
"127.0.0.45".parse().unwrap(),
cli.local_addr().unwrap().port());
assert_ne!(cli_addr.port(), 0);
// Messages to be sent
let msg1 = "What do you get if you multiply six by nine?";
let msg2 = "Forty-two";
// create the Poll object and register the sockets
let mut poll = Poll::new()?;
const SRV : Token = Token(0);
const CLI : Token = Token(1);
poll.registry().register(&mut cli, CLI, Interest::WRITABLE)?;
poll.registry().register(&mut srv, SRV, Interest::READABLE)?;
let timeout = Some(Duration::from_millis(100));
let mut events = Events::with_capacity(1);
loop
{
let nb = poll.poll(&mut events, timeout)?;
assert!(!events.is_empty(), "timeout");
for event in events.iter()
{
match event.token() {
CLI if event.is_writable() => {
// send a request (msg1) from the client to the server
let nb = cli.send_sas(msg1.as_bytes(), &srv_addr, &cli_addr.ip())?;
assert_eq!(nb, msg1.as_bytes().len());
poll.registry().reregister(&mut cli, CLI, Interest::READABLE)?;
},
SRV if event.is_readable() => {
// receive the request on the server
let (nb, peer, local) = srv.recv_sas(&mut buf)?;
assert_eq!(peer, cli_addr);
assert_eq!(local, srv_addr.ip());
assert_eq!(nb, msg1.as_bytes().len());
assert_eq!(&buf[0..nb], msg1.as_bytes());
poll.registry().reregister(&mut srv, SRV, Interest::WRITABLE)?;
},
SRV if event.is_writable() => {
// send a reply (msg2) from the server to the client
let nb = srv.send_sas(msg2.as_bytes(), &cli_addr, &srv_addr.ip())?;
assert_eq!(nb, msg2.as_bytes().len());
},
CLI if event.is_readable() => {
// receive the reply on the client
let (nb, peer, local) = cli.recv_sas(&mut buf)?;
assert_eq!(peer, srv_addr);
assert_eq!(local, cli_addr.ip());
assert_eq!(nb, msg2.as_bytes().len());
assert_eq!(&buf[0..nb], msg2.as_bytes());
return Ok(());
},
token => panic!("unexpected token: {:?}", token)
}
}
}
}
依赖关系
~0.5–1MB
~18K SLoC