跳到主要内容

TcpListener

搜索

结构体 TcpListener 

Source
pub struct TcpListener { /* private fields */ }
展开描述

TCP 套接字服务器,用于监听连接。

可以使用 accept 方法接受新的连接。

可以使用 TcpListenerStreamTcpListener 转换为 Stream

当该值被释放时,套接字将被关闭。

§Errors

请注意,接受连接可能产生各种错误,并不所有错误都一定是致命的 ‒ 例如,打开的文件描述符太多,或对端在等待接受队列中关闭了连接。如果以任何方式不处理,这些情况会终止该流。

§示例

使用 accept

use tokio::net::TcpListener;

use std::io;

async fn process_socket<T>(socket: T) {
    // do work with socket here
}

#[tokio::main]
async fn main() -> io::Result<()> {
    let listener = TcpListener::bind("127.0.0.1:8080").await?;

    loop {
        let (socket, _) = listener.accept().await?;
        process_socket(socket).await;
    }
}

实现§

Source§

impl TcpListener

Source

pub async fn bind<A: ToSocketAddrs>(addr: A) -> Result<TcpListener>

创建一个新的 TcpListener,它将绑定到指定的地址。

返回的监听器可以接受连接。

使用端口号 0 进行绑定时,会要求操作系统为该监听器分配一个端口。分配的端口可以通过 local_addr 方法查询。

地址类型可以是 ToSocketAddrs trait 的任何实现者。 如果 addr 产生多个地址,将依次尝试每个地址进行绑定,直到其中一个成功并返回监听器。如果所有地址都无法成功创建监听器,则返回最后一次尝试(即最后一个地址)的错误。

该函数会在 Unix 上为套接字设置 SO_REUSEADDR 选项。

要在绑定前配置套接字,可以使用 TcpSocket 类型。

§示例
use tokio::net::TcpListener;
use std::io;

#[tokio::main]
async fn main() -> io::Result<()> {
    let listener = TcpListener::bind("127.0.0.1:2345").await?;

    // use the listener

    Ok(())
}
Source

pub async fn accept(&self) -> Result<(TcpStream, SocketAddr)>

从该监听器接受一个新的传入连接。

该函数会在新的 TCP 连接建立时返回。连接建立后,将返回对应的 TcpStream 以及远端对端地址。

§Cancel safety

此方法可安全取消。如果该方法作为 tokio::select! 语句中的事件,且某个其他分支先完成,则可以保证此方法未接受任何新连接。

§示例
use tokio::net::TcpListener;

use std::io;

#[tokio::main]
async fn main() -> io::Result<()> {
    let listener = TcpListener::bind("127.0.0.1:8080").await?;

    match listener.accept().await {
        Ok((_socket, addr)) => println!("new client: {:?}", addr),
        Err(e) => println!("couldn't get client: {:?}", e),
    }

    Ok(())
}
Source

pub fn poll_accept( &self, cx: &mut Context<'_>, ) -> Poll<Result<(TcpStream, SocketAddr)>>

Poll 以接受一个新的传入连接到该监听器。

如果没有可接受的连接,则返回 Poll::Pending,并会通过 waker 通知当前任务。注意,对于多次调用 poll_accept,仅会调度传递给最近一次调用的 Context 中的 Waker 接收唤醒。

Source

pub fn from_std(listener: TcpListener) -> Result<TcpListener>

std::net::TcpListener 创建新的 TcpListener

该函数用于将标准库中的 TCP 监听器包装为 Tokio 的对应类型。

此 API 通常与 socket2 框架及 Socket 类型配合使用,以在它被提交给后端事件循环之前构建并定制监听器。这使得可以配置类似 SO_REUSEPORT、绑定多个地址等选项。

§Notes

调用者负责确保监听器处于非阻塞模式。否则,监听器上的所有 I/O 操作都会阻塞线程,这将导致意外行为。可以使用 set_nonblocking 设置非阻塞模式。

传递一个阻塞模式的监听器始终是错误的,该情形下的行为可能会在未来发生变化。例如,可能会引发 panic。

§示例
use std::error::Error;
use tokio::net::TcpListener;

#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
    let std_listener = std::net::TcpListener::bind("127.0.0.1:0")?;
    std_listener.set_nonblocking(true)?;
    let listener = TcpListener::from_std(std_listener)?;
    Ok(())
}
§Panics

如果该函数不是在启用了 IO 的运行时中调用,则会引发 panic。

运行时通常会在从由 tokio 运行时驱动的 future 中调用此函数时隐式设置,否则可以使用 Runtime::enter 函数显式设置。

Source

pub fn into_std(self) -> Result<TcpListener>

tokio::net::TcpListener 转换为 std::net::TcpListener

返回的 std::net::TcpListener 的非阻塞模式将被设置为 true。如有需要,可使用 set_nonblocking 修改阻塞模式。

§示例
use std::error::Error;

#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
    let tokio_listener = tokio::net::TcpListener::bind("127.0.0.1:0").await?;
    let std_listener = tokio_listener.into_std()?;
    std_listener.set_nonblocking(false)?;
    Ok(())
}
Source

pub fn local_addr(&self) -> Result<SocketAddr>

返回该监听器绑定的本地地址。

这在某些场景下很有用,例如绑定到端口 0 时,可以查看实际绑定到了哪个端口。

§示例
use tokio::net::TcpListener;

use std::io;
use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4};

#[tokio::main]
async fn main() -> io::Result<()> {
    let listener = TcpListener::bind("127.0.0.1:8080").await?;

    assert_eq!(listener.local_addr()?,
               SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080)));

    Ok(())
}
Source

pub fn ttl(&self) -> Result<u32>

获取该套接字的 IP_TTL 选项值。

关于此选项的更多信息,请参见 set_ttl

§示例
use tokio::net::TcpListener;

use std::io;

#[tokio::main]
async fn main() -> io::Result<()> {
   let listener = TcpListener::bind("127.0.0.1:0").await?;

   listener.set_ttl(100).expect("could not set TTL");
   assert_eq!(listener.ttl()?, 100);

   Ok(())
}
Source

pub fn set_ttl(&self, ttl: u32) -> Result<()>

为该套接字设置 IP_TTL 选项的值。

此值设置了从该套接字发出的每个数据包中使用的生存时间字段。

§示例
use tokio::net::TcpListener;

use std::io;

#[tokio::main]
async fn main() -> io::Result<()> {
    let listener = TcpListener::bind("127.0.0.1:0").await?;

    listener.set_ttl(100).expect("could not set TTL");

    Ok(())
}

Trait 实现§

Source§

impl AsRawSocket for TcpListener

Available on docsrs, or Windows only.
Source§

fn as_raw_socket(&self) -> RawSocket

Extracts the raw socket. 更多信息
Source§

impl AsSocket for TcpListener

Available on docsrs, or Windows only.
Source§

fn as_socket(&self) -> BorrowedSocket<'_>

借用此套接字。
Source§

impl Debug for TcpListener

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

使用给定的格式化器格式化此值。 更多信息
Source§

impl TryFrom<TcpListener> for TcpListener

Source§

fn try_from(stream: TcpListener) -> Result<Self, Self::Error>

消耗流,返回 tokio 的 I/O 对象。

这等同于 TcpListener::from_std(stream)

Source§

type Error = Error

转换出错时返回的类型。

自动 Trait 实现§

Blanket 实现§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. 更多信息
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. 更多信息
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. 更多信息
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

原样返回传入的参数。

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

调用 U::from(self)

也就是说,此转换的具体行为取决于 From<T> for U 的实现方式。

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

转换出错时返回的类型。
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

执行转换。
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

转换出错时返回的类型。
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

执行转换。