diff --git a/src/net/tcp/stream.rs b/src/net/tcp/stream.rs index ecc850fec..029f186b4 100644 --- a/src/net/tcp/stream.rs +++ b/src/net/tcp/stream.rs @@ -49,6 +49,30 @@ pub struct TcpStream { impl TcpStream { /// Create a new TCP stream and issue a non-blocking connect to the /// specified address. + /// + /// # Notes + /// + /// The returned `TcpStream` may not be connected (and thus usable), unlike + /// the API found in `std::net::TcpStream`. Because Mio issues a + /// *non-blocking* connect it will not block the thread and instead return + /// an unconnected `TcpStream`. + /// + /// Ensuring the returned stream is connected is surprisingly complex when + /// considering cross-platform support. Doing this properly should follow + /// the steps below, an example implementation can be found + /// [here](https://github.com/Thomasdezeeuw/heph/blob/0c4f1ab3eaf08bea1d65776528bfd6114c9f8374/src/net/tcp/stream.rs#L560-L622). + /// + /// 1. Call `TcpStream::connect` + /// 2. Register the returned stream with at least [read interest]. + /// 3. Wait for a (readable) event. + /// 4. Check `TcpStream::peer_addr`. If it returns `libc::EINPROGRESS` or + /// `ErrorKind::NotConnected` it means the stream is not yet connected, + /// go back to step 3. If it returns an address it means the stream is + /// connected, go to step 5. If another error is returned something + /// whent wrong. + /// 5. Now the stream can be used. + /// + /// [read interest]: Interest::READABLE pub fn connect(addr: SocketAddr) -> io::Result { let socket = new_for_addr(addr)?; #[cfg(unix)]