Изящный выход TcpListener.incoming () - PullRequest
1 голос
/ 20 июня 2019

Из библиотеки ржавчины std net:

let listener = TcpListener::bind(("127.0.0.1", port)).unwrap();

info!("Opened socket on localhost port {}", port);

// accept connections and process them serially
for stream in listener.incoming() {
    break;
}

info!("closed socket");

Как заставить слушателя перестать слушать?В API говорится, что когда слушатель отбрасывается, он останавливается.Но как мы можем отбросить его, если incoming() является блокирующим вызовом?Желательно без внешних ящиков, таких как Tokio / Mio.

1 Ответ

2 голосов
/ 20 июня 2019

Вы захотите перевести TcpListener в неблокирующий режим, используя метод set_nonblocking (), например так:

use std::io;
use std::net::TcpListener;

let listener = TcpListener::bind("127.0.0.1:7878").unwrap();
listener.set_nonblocking(true).expect("Cannot set non-blocking");

for stream in listener.incoming() {
    match stream {
        Ok(s) => {
            // do something with the TcpStream
            handle_connection(s);
        }
        Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
            // Decide if we should exit
            break;
            // Decide if we should try to accept a connection again
            continue;
        }
        Err(e) => panic!("encountered IO error: {}", e),
    }
}

Вместо ожидания соединения входящий вызов () немедленно вернетсяТип результата <>.Если Result is Ok (), значит, соединение установлено, и вы можете его обработать.Если Результатом является Err (WillBlock), это на самом деле не ошибка, просто не было ожидающего соединения в тот момент, когда входящий () проверил сокет.

Обратите внимание, что в случае WillBlock выможет потребоваться установить sleep () или что-то еще, прежде чем продолжить, в противном случае ваша программа будет быстро опрашивать функцию входящего (), проверяя соединение, что приводит к высокой загрузке ЦП.

Пример кода, адаптированный с здесь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...