使用期货的Rust echo服务器和客户端永远阻止自己

sim*_*666 3 client echo rust server

将此代码用于服务器,并为客户端代码修改了本教程.当客户端连接到服务器时,它会永久阻止自身.

服务器:

extern crate futures;
extern crate futures_io;
extern crate futures_mio;

use std::net::SocketAddr;

use futures::Future;
use futures_io::{copy, TaskIo};
use futures::stream::Stream;

fn main() {
    let addr = "127.0.0.1:8080".parse::<SocketAddr>().unwrap();

    let mut l = futures_mio::Loop::new().unwrap();

    let server = l.handle().tcp_listen(&addr);

    let done = server.and_then(move |socket| {
        println!("Listening on: {}", addr);

        socket.incoming().for_each(|(socket, addr)| {
            let io = TaskIo::new(socket);
            let pair = io.map(|io| io.split());
            let amt = pair.and_then(|(reader, writer)| {
                copy(reader, writer)
            });
            amt.map(move |amt| {
                println!("wrote {} bytes to {}", amt, addr)
            }).forget();

            Ok(())
        })
    });
    l.run(done).unwrap();
}
Run Code Online (Sandbox Code Playgroud)

客户:

extern crate futures;
extern crate futures_io;
extern crate futures_mio;

use std::net::SocketAddr;

use futures::Future;
use futures_mio::Loop;

fn main() {
    let mut lp = Loop::new().unwrap();
    let addr = "127.0.0.1:8080".parse::<SocketAddr>().unwrap();

    let socket = lp.handle().tcp_connect(&addr);

    let request = socket.and_then(|socket| {
        futures_io::write_all(socket, b"Hello!")
    });

    let response = request.and_then(|(socket, _)| {
        futures_io::read_to_end(socket, Vec::new())
    });

    let data = lp.run(response).unwrap();
    println!("{}", String::from_utf8_lossy(&data));
}
Run Code Online (Sandbox Code Playgroud)

She*_*ter 8

这个问题与期货无关.你有一个打开的套接字,你要求"读到它直到结束".是什么决定了结局?在这种情况下,它是在插座关闭时; 那么什么时候?

特技提问!

  • 当服务器的写入套接字关闭时,客户端的读取套接字关闭.
  • 当服务器的读取套接字关闭时,服务器的写入套接字关闭.
  • 当客户端的写入套接字关闭时,服务器的读取套接字关闭.

那么什么时候发生?因为没有特定的代码,所以当套接字被删除时它会关闭,所以:

  • 客户端的写入套接字在客户端结束时关闭.

因而陷入僵局.可以通过显式关闭套接字的一半来解决此问题:

let response = request.and_then(|(socket, _)| {
    socket.shutdown(std::net::Shutdown::Write).expect("Couldn't shut down");
    read_to_end(socket, Vec::new())
});
Run Code Online (Sandbox Code Playgroud)