| 15 | } |
| 16 | |
| 17 | fn new_socket(addr: SocketAddr, reuse: bool, buf_size: usize) -> Result<Socket, std::io::Error> { |
| 18 | let socket = match addr { |
| 19 | SocketAddr::V4(..) => Socket::new(Domain::ipv4(), Type::dgram(), None), |
| 20 | SocketAddr::V6(..) => Socket::new(Domain::ipv6(), Type::dgram(), None), |
| 21 | }?; |
| 22 | if reuse { |
| 23 | // windows has no reuse_port, but it's reuse_address |
| 24 | // almost equals to unix's reuse_port + reuse_address, |
| 25 | // though may introduce nondeterministic behavior |
| 26 | #[cfg(unix)] |
| 27 | socket.set_reuse_port(true).ok(); |
| 28 | socket.set_reuse_address(true).ok(); |
| 29 | } |
| 30 | // only nonblocking work with tokio, https://stackoverflow.com/questions/64649405/receiver-on-tokiompscchannel-only-receives-messages-when-buffer-is-full |
| 31 | socket.set_nonblocking(true)?; |
| 32 | if buf_size > 0 { |
| 33 | socket.set_recv_buffer_size(buf_size).ok(); |
| 34 | } |
| 35 | log::debug!( |
| 36 | "Receive buf size of udp {}: {:?}", |
| 37 | addr, |
| 38 | socket.recv_buffer_size() |
| 39 | ); |
| 40 | if addr.is_ipv6() && addr.ip().is_unspecified() && addr.port() > 0 { |
| 41 | socket.set_only_v6(false).ok(); |
| 42 | } |
| 43 | socket.bind(&addr.into())?; |
| 44 | Ok(socket) |
| 45 | } |
| 46 | |
| 47 | impl FramedSocket { |
| 48 | pub async fn new<T: ToSocketAddrs>(addr: T) -> ResultType<Self> { |