diff --git a/schemes/tcpd/src/main.rs b/schemes/tcpd/src/main.rs
index 8d124d8..8878b00 100644
--- a/schemes/tcpd/src/main.rs
+++ b/schemes/tcpd/src/main.rs
@@ -660,14 +660,16 @@ impl SchemeMut for Tcpd {
             Handle::Tcp(ref mut handle) => {
                 if ! handle.is_connected() {
                     return Err(Error::new(ENOTCONN));
-                } else if let Some((_ip, tcp)) = handle.data.pop_front() {
-                    let mut i = 0;
-                    while i < buf.len() && i < tcp.data.len() {
-                        buf[i] = tcp.data[i];
-                        i += 1;
+                } else if let Some((ip, mut tcp)) = handle.data.pop_front() {
+                    let len = std::cmp::min(buf.len(), tcp.data.len());
+                    for (i, c) in tcp.data.drain(0..len).enumerate() {
+                        buf[i] = c;
+                    }
+                    if !tcp.data.is_empty() {
+                        handle.data.push_front((ip, tcp));
                     }
 
-                    return Ok(i);
+                    return Ok(len);
                 } else if handle.flags & O_NONBLOCK == O_NONBLOCK || handle.read_closed() {
                     return Ok(0);
                 } else {