S-JIS[2024-12-15] 変更履歴

tokio TcpStreamメモ

RusttokioクレートのnetモジュールのTcpStream構造体のメモ。


概要

TcpStreamは、TCP/IP通信を実現する構造体。

tokioのTcpStreamを使うには、netフィーチャーを指定する必要がある。
また、送受信に使う関数(readやwrite)はioモジュールのトレイトを使うので、io-utilフィーチャーも指定する必要がある。

Cargo.toml:

[dependencies]
tokio = { version = "1.42.0", features=[〜, "net", "io-util"] }

TcpStreamの例

TCPクライアントの例。

use tokio::io::{AsyncReadExt, AsyncWriteExt};
use tokio::net::TcpStream;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let mut stream = TcpStream::connect("localhost:8080").await?;

    stream.write_all(b"send data").await?;

    let mut buf = [0u8; 1024];
    let read_len = stream.read(&mut buf).await?;

    Ok(())
}

送信を行うwrite系メソッドはAsyncWriteExtトレイトで定義されているので、AsyncWriteExtをインポートする必要がある。
受信を行うreada系メソッドはAsyncReadExtトレイトで定義されているので、AsyncReadExtをインポートする必要がある。

write_allメソッドは、引数で指定された全データを送信する。
readメソッドは、受信を行い、受信されたバイト数を返す。
read_extractメソッドは、引数で指定されたバッファーが埋まるまで受信する。


送受信を別オブジェクトで実行する例

TcpStreamの受信と送信を別オブジェクトに分けて使うことが出来る。

use tokio::io::{AsyncReadExt, AsyncWriteExt};
use tokio::net::TcpStream;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let stream = TcpStream::connect("localhost:8080").await?;
    let (mut reader, mut writer) = tokio::io::split(stream);

    writer.write_all(b"send data").await?;

    let mut buf = [0u8; 1024];
    let read_len = reader.read(&mut buf).await?;

    Ok(())
}

分割したreaderとwriterを構造体のフィールドに保持する例

use tokio::io::{AsyncReadExt, AsyncWriteExt, ReadHalf, WriteHalf};
use tokio::net::TcpStream;
struct SplitExample {
    reader: ReadHalf<TcpStream>,
    writer: WriteHalf<TcpStream>,
}

impl SplitExample {
    fn new(stream: TcpStream) -> SplitExample {
        let (reader, writer) = tokio::io::split(stream);
        SplitExample { reader, writer }
    }

    async fn write_all(&mut self, src: &[u8]) -> Result<(), std::io::Error> {
        self.writer.write_all(src).await
    }

    async fn read(&mut self, buf: &mut [u8]) -> Result<usize, std::io::Error> {
        self.reader.read(buf).await
    }
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let stream = TcpStream::connect("localhost:8080").await?;
    let mut example = SplitExample::new(stream);

    example.write_all(b"send data").await?;

    let mut buf = [0u8; 1024];
    let read_len = example.read(&mut buf).await?;

    Ok(())
}

tokio::netへ戻る / tokioへ戻る / Rustへ戻る / 技術メモへ戻る
メールの送信先:ひしだま