使用期货的Rust回声服务器和客户端将永远阻止自己 [英] Rust echo server and client using futures blocks itself forever

查看:133
本文介绍了使用期货的Rust回声服务器和客户端将永远阻止自己的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用了此代码服务器,并为客户端修改了本教程代码.客户端连接到服务器后,它将永远被阻止.

I used this code for the server, and modified this tutorial for the client code. When a client connects to the server, it blocks itself forever.

服务器:

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();
}

客户:

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));
}

推荐答案

该问题与期货无关.您有一个开放的套接字,并且要求读到最后". 什么决定结束?在这种情况下,是插座关闭的时候.那是什么时候?

The problem has nothing to do with futures. You have an open socket and you ask to "read it until the end". What determines the end? In this case, it's when the socket is closed; so when is that?

技巧问题!

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

那什么时候发生?因为没有专门执行此操作的代码,所以在删除套接字时它将关闭,所以:

So when does that happen? Because there's no code that does it specifically, it will close when the socket is dropped, so:

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

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

Thus the deadlock. The issue can be fixed by explicitly closing the write half of the socket:

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

这篇关于使用期货的Rust回声服务器和客户端将永远阻止自己的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆