| # Mio – Metal IO |
| |
| Mio is a fast, low-level I/O library for Rust focusing on non-blocking APIs and |
| event notification for building high performance I/O apps with as little |
| overhead as possible over the OS abstractions. |
| |
| [![Crates.io][crates-badge]][crates-url] |
| [![MIT licensed][mit-badge]][mit-url] |
| [![Build Status][azure-badge]][azure-url] |
| [![Build Status][cirrus-badge]][cirrus-url] |
| |
| [crates-badge]: https://img.shields.io/crates/v/mio.svg |
| [crates-url]: https://crates.io/crates/mio |
| [mit-badge]: https://img.shields.io/badge/license-MIT-blue.svg |
| [mit-url]: LICENSE |
| [azure-badge]: https://dev.azure.com/tokio-rs/Tokio/_apis/build/status/tokio-rs.mio?branchName=master |
| [azure-url]: https://dev.azure.com/tokio-rs/Tokio/_build/latest?definitionId=2&branchName=master |
| [cirrus-badge]: https://api.cirrus-ci.com/github/tokio-rs/mio.svg |
| [cirrus-url]: https://cirrus-ci.com/github/tokio-rs/mio |
| |
| **API documentation** |
| |
| * [master](https://tokio-rs.github.io/mio/doc/mio/) |
| * [v0.8](https://docs.rs/mio/^0.8) |
| * [v0.7](https://docs.rs/mio/^0.7) |
| * [v0.6](https://docs.rs/mio/^0.6) |
| |
| This is a low level library, if you are looking for something easier to get |
| started with, see [Tokio](https://tokio.rs). |
| |
| ## Usage |
| |
| To use `mio`, first add this to your `Cargo.toml`: |
| |
| ```toml |
| [dependencies] |
| mio = "0.8" |
| ``` |
| |
| Next we can start using Mio. The following is quick introduction using |
| `TcpListener` and `TcpStream`. Note that `features = ["os-poll", "net"]` must be |
| specified for this example. |
| |
| ```rust |
| use std::error::Error; |
| |
| use mio::net::{TcpListener, TcpStream}; |
| use mio::{Events, Interest, Poll, Token}; |
| |
| // Some tokens to allow us to identify which event is for which socket. |
| const SERVER: Token = Token(0); |
| const CLIENT: Token = Token(1); |
| |
| fn main() -> Result<(), Box<dyn Error>> { |
| // Create a poll instance. |
| let mut poll = Poll::new()?; |
| // Create storage for events. |
| let mut events = Events::with_capacity(128); |
| |
| // Setup the server socket. |
| let addr = "127.0.0.1:13265".parse()?; |
| let mut server = TcpListener::bind(addr)?; |
| // Start listening for incoming connections. |
| poll.registry() |
| .register(&mut server, SERVER, Interest::READABLE)?; |
| |
| // Setup the client socket. |
| let mut client = TcpStream::connect(addr)?; |
| // Register the socket. |
| poll.registry() |
| .register(&mut client, CLIENT, Interest::READABLE | Interest::WRITABLE)?; |
| |
| // Start an event loop. |
| loop { |
| // Poll Mio for events, blocking until we get an event. |
| poll.poll(&mut events, None)?; |
| |
| // Process each event. |
| for event in events.iter() { |
| // We can use the token we previously provided to `register` to |
| // determine for which socket the event is. |
| match event.token() { |
| SERVER => { |
| // If this is an event for the server, it means a connection |
| // is ready to be accepted. |
| // |
| // Accept the connection and drop it immediately. This will |
| // close the socket and notify the client of the EOF. |
| let connection = server.accept(); |
| drop(connection); |
| } |
| CLIENT => { |
| if event.is_writable() { |
| // We can (likely) write to the socket without blocking. |
| } |
| |
| if event.is_readable() { |
| // We can (likely) read from the socket without blocking. |
| } |
| |
| // Since the server just shuts down the connection, let's |
| // just exit from our event loop. |
| return Ok(()); |
| } |
| // We don't expect any events with tokens other than those we provided. |
| _ => unreachable!(), |
| } |
| } |
| } |
| } |
| ``` |
| |
| ## Features |
| |
| * Non-blocking TCP, UDP |
| * I/O event queue backed by epoll, kqueue, and IOCP |
| * Zero allocations at runtime |
| * Platform specific extensions |
| |
| ## Non-goals |
| |
| The following are specifically omitted from Mio and are left to the user |
| or higher-level libraries. |
| |
| * File operations |
| * Thread pools / multi-threaded event loop |
| * Timers |
| |
| ## Platforms |
| |
| Currently supported platforms: |
| |
| * Android (API level 21) |
| * DragonFly BSD |
| * FreeBSD |
| * Linux |
| * NetBSD |
| * OpenBSD |
| * Windows |
| * iOS |
| * macOS |
| * Wine (version 6.11+, see [issue #1444]) |
| |
| There are potentially others. If you find that Mio works on another |
| platform, submit a PR to update the list! |
| |
| Mio can handle interfacing with each of the event systems of the aforementioned |
| platforms. The details of their implementation are further discussed in the |
| `Poll` type of the API documentation (see above). |
| |
| The Windows implementation for polling sockets is using the [wepoll] strategy. |
| This uses the Windows AFD system to access socket readiness events. |
| |
| [wepoll]: https://github.com/piscisaureus/wepoll |
| [issue #1444]: https://github.com/tokio-rs/mio/issues/1444 |
| |
| ### Unsupported |
| |
| * Haiku, see [issue #1472] |
| * Solaris, see [issue #1152] |
| |
| [issue #1472]: https://github.com/tokio-rs/mio/issues/1472 |
| [issue #1152]: https://github.com/tokio-rs/mio/issues/1152 |
| |
| ## Community |
| |
| A group of Mio users hang out on [Discord], this can be a good place to go for |
| questions. |
| |
| [Discord]: https://discord.gg/tokio |
| |
| ## Contributing |
| |
| Interested in getting involved? We would love to help you! For simple |
| bug fixes, just submit a PR with the fix and we can discuss the fix |
| directly in the PR. If the fix is more complex, start with an issue. |
| |
| If you want to propose an API change, create an issue to start a |
| discussion with the community. Also, feel free to talk with us in Discord. |
| |
| Finally, be kind. We support the [Rust Code of Conduct](https://www.rust-lang.org/policies/code-of-conduct). |