Struct std::net::TcpStream1.0.0[][src]

pub struct TcpStream(_);
Expand description

本地套接字和远程套接字之间的 TCP 流。

在通过 connect 到远程主机或 acceptTcpListener 上创建连接来创建 TcpStream 后,数据可以由 读取写入 传输到该 TcpStream

丢弃该值时,连接将关闭。也可以使用 shutdown 方法单独关闭连接的读取和写入部分。

传输控制协议在 IETF RFC 793 中指定。

Examples

use std::io::prelude::*;
use std::net::TcpStream;

fn main() -> std::io::Result<()> {
    let mut stream = TcpStream::connect("127.0.0.1:34254")?;

    stream.write(&[1])?;
    stream.read(&mut [0; 128])?;
    Ok(())
} // 流在这里关闭
Run

Implementations

打开到远程主机的 TCP 连接。

addr 是远程主机的地址。 可以提供任何实现 ToSocketAddrs trait 的地址。有关具体示例,请参见此 trait 文档。

如果 addr 产生多个地址,则将使用每个地址尝试 connect,直到连接成功。 如果没有一个地址导致连接成功,则返回从上一次连接尝试 (最后一个地址) 返回的错误。

Examples

打开到 127.0.0.1:8080 的 TCP 连接:

use std::net::TcpStream;

if let Ok(stream) = TcpStream::connect("127.0.0.1:8080") {
    println!("Connected to the server!");
} else {
    println!("Couldn't connect to server...");
}
Run

打开到 127.0.0.1:8080 的 TCP 连接。如果连接失败,请打开与 127.0.0.1:8081 的 TCP 连接:

use std::net::{SocketAddr, TcpStream};

let addrs = [
    SocketAddr::from(([127, 0, 0, 1], 8080)),
    SocketAddr::from(([127, 0, 0, 1], 8081)),
];
if let Ok(stream) = TcpStream::connect(&addrs[..]) {
    println!("Connected to the server!");
} else {
    println!("Couldn't connect to server...");
}
Run

超时打开与远程主机的 TCP 连接。

connect 不同,由于必须将超时应用于单个地址,因此 connect_timeout 仅占用一个 SocketAddr

向此函数传递零 Duration 是错误的。

TcpStream 上的其他方法不同,这并不对应于单个系统调用。 相反,它以非阻塞模式调用 connect,然后使用特定于操作系统的机制来等待连接请求的完成。

返回此 TCP 连接的远程对等方的套接字地址。

Examples
use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4, TcpStream};

let stream = TcpStream::connect("127.0.0.1:8080")
                       .expect("Couldn't connect to the server...");
assert_eq!(stream.peer_addr().unwrap(),
           SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080)));
Run

返回此 TCP 连接本地一半的套接字地址。

Examples
use std::net::{IpAddr, Ipv4Addr, TcpStream};

let stream = TcpStream::connect("127.0.0.1:8080")
                       .expect("Couldn't connect to the server...");
assert_eq!(stream.local_addr().unwrap().ip(),
           IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)));
Run

关闭此连接的读取,写入或两半。

此函数将导致指定部分上的所有未决和 future I/O 立即以适当的值返回 (请参见 Shutdown 的文档)。

特定于平台的行为

取决于操作系统,多次调用此函数可能会导致不同的行为。 在 Linux 上,第二个调用将返回 Ok(()),但在 macOS 上,它将返回 ErrorKind::NotConnected。 future 可能会改变。

Examples
use std::net::{Shutdown, TcpStream};

let stream = TcpStream::connect("127.0.0.1:8080")
                       .expect("Couldn't connect to the server...");
stream.shutdown(Shutdown::Both).expect("shutdown call failed");
Run

为底层套接字创建一个新的独立的拥有所有权的句柄。

返回的 TcpStream 是与此对象引用相同的流的引用。 两个句柄将读取和写入相同的数据流,并且在一个流上设置的选项将传播到另一流。

Examples
use std::net::TcpStream;

let stream = TcpStream::connect("127.0.0.1:8080")
                       .expect("Couldn't connect to the server...");
let stream_clone = stream.try_clone().expect("clone failed...");
Run

将读取超时设置为指定的超时。

如果指定的值为 None,则 read 调用将无限期阻塞。 如果将零 Duration 传递给此方法,则返回 Err

特定于平台的行为

由于设置此选项而导致读取超时时,平台可能会返回不同的错误代码。 例如,Unix 通常返回类型为 WouldBlock 的错误,但是 Windows 可能返回 TimedOut

Examples
use std::net::TcpStream;

let stream = TcpStream::connect("127.0.0.1:8080")
                       .expect("Couldn't connect to the server...");
stream.set_read_timeout(None).expect("set_read_timeout call failed");
Run

如果将零 Duration 传递给此方法,则返回 Err

use std::io;
use std::net::TcpStream;
use std::time::Duration;

let stream = TcpStream::connect("127.0.0.1:8080").unwrap();
let result = stream.set_read_timeout(Some(Duration::new(0, 0)));
let err = result.unwrap_err();
assert_eq!(err.kind(), io::ErrorKind::InvalidInput)
Run

将写超时设置为指定的超时。

如果指定的值为 None,则 write 调用将无限期阻塞。 如果将零 Duration 传递给此方法,则返回 Err

特定于平台的行为

由于设置此选项而导致写超时时,平台可能会返回不同的错误代码。 例如,Unix 通常返回类型为 WouldBlock 的错误,但是 Windows 可能返回 TimedOut

Examples
use std::net::TcpStream;

let stream = TcpStream::connect("127.0.0.1:8080")
                       .expect("Couldn't connect to the server...");
stream.set_write_timeout(None).expect("set_write_timeout call failed");
Run

如果将零 Duration 传递给此方法,则返回 Err

use std::io;
use std::net::TcpStream;
use std::time::Duration;

let stream = TcpStream::connect("127.0.0.1:8080").unwrap();
let result = stream.set_write_timeout(Some(Duration::new(0, 0)));
let err = result.unwrap_err();
assert_eq!(err.kind(), io::ErrorKind::InvalidInput)
Run

返回此套接字的读取超时。

如果超时为 None,则 read 调用将无限期阻塞。

特定于平台的行为

某些平台不提供对当前超时的访问。

Examples
use std::net::TcpStream;

let stream = TcpStream::connect("127.0.0.1:8080")
                       .expect("Couldn't connect to the server...");
stream.set_read_timeout(None).expect("set_read_timeout call failed");
assert_eq!(stream.read_timeout().unwrap(), None);
Run

返回此套接字的写入超时。

如果超时为 None,则 write 调用将无限期阻塞。

特定于平台的行为

某些平台不提供对当前超时的访问。

Examples
use std::net::TcpStream;

let stream = TcpStream::connect("127.0.0.1:8080")
                       .expect("Couldn't connect to the server...");
stream.set_write_timeout(None).expect("set_write_timeout call failed");
assert_eq!(stream.write_timeout().unwrap(), None);
Run

从套接字所连接的远程地址接收套接字上的数据,而无需从队列中删除该数据。

成功时,返回偷看的字节数。

连续调用返回相同的数据。 这是通过将 MSG_PEEK 作为标志传递给底层的 recv 系统调用来实现的。

Examples
use std::net::TcpStream;

let stream = TcpStream::connect("127.0.0.1:8000")
                       .expect("couldn't bind to address");
let mut buf = [0; 10];
let len = stream.peek(&mut buf).expect("peek failed");
Run
🔬 This is a nightly-only experimental API. (tcp_linger #88494)

设置此套接字上 SO_LINGER 选项的值。

此值控制当数据仍有待发送时如何关闭套接字。 如果设置了 SO_LINGER,则当系统尝试发送挂起的数据时,套接字将在指定的持续时间内保持打开状态。

否则,系统可能会立即关闭套接字,或等待默认超时。

Examples
#![feature(tcp_linger)]

use std::net::TcpStream;
use std::time::Duration;

let stream = TcpStream::connect("127.0.0.1:8080")
                       .expect("Couldn't connect to the server...");
stream.set_linger(Some(Duration::from_secs(0))).expect("set_linger call failed");
Run
🔬 This is a nightly-only experimental API. (tcp_linger #88494)

获取此套接字上 SO_LINGER 选项的值。

有关此选项的更多信息,请参见 TcpStream::set_linger

Examples
#![feature(tcp_linger)]

use std::net::TcpStream;
use std::time::Duration;

let stream = TcpStream::connect("127.0.0.1:8080")
                       .expect("Couldn't connect to the server...");
stream.set_linger(Some(Duration::from_secs(0))).expect("set_linger call failed");
assert_eq!(stream.linger().unwrap(), Some(Duration::from_secs(0)));
Run

设置此套接字上 TCP_NODELAY 选项的值。

如果设置,则此选项禁用 Nagle 算法。 这意味着即使只有少量数据,也总是尽快发送段。 如果未设置,则对数据进行缓冲,直到有足够的数据量可以发送出去,从而避免了频繁发送小数据包。

Examples
use std::net::TcpStream;

let stream = TcpStream::connect("127.0.0.1:8080")
                       .expect("Couldn't connect to the server...");
stream.set_nodelay(true).expect("set_nodelay call failed");
Run

获取此套接字上 TCP_NODELAY 选项的值。

有关此选项的更多信息,请参见 TcpStream::set_nodelay

Examples
use std::net::TcpStream;

let stream = TcpStream::connect("127.0.0.1:8080")
                       .expect("Couldn't connect to the server...");
stream.set_nodelay(true).expect("set_nodelay call failed");
assert_eq!(stream.nodelay().unwrap_or(false), true);
Run

设置此套接字上 IP_TTL 选项的值。

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

Examples
use std::net::TcpStream;

let stream = TcpStream::connect("127.0.0.1:8080")
                       .expect("Couldn't connect to the server...");
stream.set_ttl(100).expect("set_ttl call failed");
Run

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

有关此选项的更多信息,请参见 TcpStream::set_ttl

Examples
use std::net::TcpStream;

let stream = TcpStream::connect("127.0.0.1:8080")
                       .expect("Couldn't connect to the server...");
stream.set_ttl(100).expect("set_ttl call failed");
assert_eq!(stream.ttl().unwrap_or(0), 100);
Run

获取此套接字上 SO_ERROR 选项的值。

这将检索底层套接字中存储的错误,从而清除进程中的字段。 这对于检查两次调用之间的错误很有用。

Examples
use std::net::TcpStream;

let stream = TcpStream::connect("127.0.0.1:8080")
                       .expect("Couldn't connect to the server...");
stream.take_error().expect("No error was expected...");
Run

将此 TCP 流移入或移出非阻塞模式。

这将导致 readwriterecvsend 操作变为非阻塞,即立即从其调用中返回。

如果 IO 操作成功,则返回 Ok,并且不需要进一步的操作。 如果 IO 操作无法完成,需要重试,则返回类型为 io::ErrorKind::WouldBlock 的错误。

在 Unix 平台上,调用此方法相当于调用 fcntl FIONBIO。 在 Windows 上,调用此方法对应于调用 ioctlsocket FIONBIO

Examples

在非阻塞模式下从 TCP 流读取字节:

use std::io::{self, Read};
use std::net::TcpStream;

let mut stream = TcpStream::connect("127.0.0.1:7878")
    .expect("Couldn't connect to the server...");
stream.set_nonblocking(true).expect("set_nonblocking call failed");

let mut buf = vec![];
loop {
    match stream.read_to_end(&mut buf) {
        Ok(_) => break,
        Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
            // 等待网络套接字就绪,通常通过平台特定的 API (例如 epoll 或 IOCP) 实现
            wait_for_fd();
        }
        Err(e) => panic!("encountered IO error: {}", e),
    };
};
println!("bytes: {:?}", buf);
Run

Trait Implementations

🔬 This is a nightly-only experimental API. (io_safety #87074)
This is supported on Unix only.

借用文件描述符。 Read more

This is supported on Unix only.

提取原始文件描述符。 Read more

从此对象中提取底层原始套接字。

🔬 This is a nightly-only experimental API. (io_safety #87074)

借用套接字。

使用给定的格式化程序格式化该值。 Read more

执行转换。

执行转换。

执行转换。

执行转换。

This is supported on Unix only.

根据给定的原始文件描述符构造 Self 的新实例。 Read more

从给定的原始套接字创建一个新的 I/O 对象。 Read more

This is supported on Unix only.

消费这个对象,返回原始的底层文件描述符。 Read more

消耗此对象,返回原始底层套接字。 Read more

从该源中提取一些字节到指定的缓冲区中,返回读取的字节数。 Read more

read 相似,不同之处在于它读入缓冲区的一部分。 Read more

🔬 This is a nightly-only experimental API. (can_vector #69941)

确定此 Read 是否具有有效的 read_vectored 实现。 Read more

🔬 This is a nightly-only experimental API. (read_initializer #42788)

确定此 Reader 是否可以使用未初始化内存的缓冲区。 Read more

读取所有字节,直到此源中的 EOF 为止,然后将它们放入 bufRead more

读取这个源中的所有字节,直到 EOF 为止,然后将它们追加到 bufRead more

读取填充 buf 所需的确切字节数。 Read more

为这个 Read 实例创建一个基于引用的适配器。 Read more

将此 Read 实例的字节数转换为 IteratorRead more

创建一个适配器,将这个流与另一个链接起来。 Read more

创建一个适配器,最多从中读取 limit 个字节。 Read more

从该源中提取一些字节到指定的缓冲区中,返回读取的字节数。 Read more

read 相似,不同之处在于它读入缓冲区的一部分。 Read more

🔬 This is a nightly-only experimental API. (can_vector #69941)

确定此 Read 是否具有有效的 read_vectored 实现。 Read more

🔬 This is a nightly-only experimental API. (read_initializer #42788)

确定此 Reader 是否可以使用未初始化内存的缓冲区。 Read more

读取所有字节,直到此源中的 EOF 为止,然后将它们放入 bufRead more

读取这个源中的所有字节,直到 EOF 为止,然后将它们追加到 bufRead more

读取填充 buf 所需的确切字节数。 Read more

为这个 Read 实例创建一个基于引用的适配器。 Read more

将此 Read 实例的字节数转换为 IteratorRead more

创建一个适配器,将这个流与另一个链接起来。 Read more

创建一个适配器,最多从中读取 limit 个字节。 Read more

在此 writer 中写入一个缓冲区,返回写入的字节数。 Read more

类似于 write,不同之处在于它是从缓冲区切片中写入数据的。 Read more

🔬 This is a nightly-only experimental API. (can_vector #69941)

确定此 Writer 是否具有有效的 write_vectored 实现。 Read more

刷新此输出流,确保所有中间缓冲的内容均到达其目的地。 Read more

尝试将整个缓冲区写入此 writer。 Read more

🔬 This is a nightly-only experimental API. (write_all_vectored #70436)

尝试将多个缓冲区写入此 writer。 Read more

将格式化的字符串写入此 writer,返回遇到的任何错误。 Read more

为这个 Write 实例创建一个 “by reference” 适配器。 Read more

在此 writer 中写入一个缓冲区,返回写入的字节数。 Read more

类似于 write,不同之处在于它是从缓冲区切片中写入数据的。 Read more

🔬 This is a nightly-only experimental API. (can_vector #69941)

确定此 Writer 是否具有有效的 write_vectored 实现。 Read more

刷新此输出流,确保所有中间缓冲的内容均到达其目的地。 Read more

尝试将整个缓冲区写入此 writer。 Read more

🔬 This is a nightly-only experimental API. (write_all_vectored #70436)

尝试将多个缓冲区写入此 writer。 Read more

将格式化的字符串写入此 writer,返回遇到的任何错误。 Read more

为这个 Write 实例创建一个 “by reference” 适配器。 Read more

Auto Trait Implementations

Blanket Implementations

获取 selfTypeIdRead more

从拥有的值中一成不变地借用。 Read more

从拥有的值中借用。 Read more

执行转换。

执行转换。

发生转换错误时返回的类型。

执行转换。

发生转换错误时返回的类型。

执行转换。