2. TCP客户端连接

任务说明

本案例实现一个完整的TCP客户端程序:连接指定服务器地址与端口,向服务器发送一条文本消息,并接收服务器返回的数据后打印输出。客户端需处理连接失败、发送失败与接收超时等基本错误场景。

实现方案

使用Rust标准库 std::net::TcpStream 完成TCP连接与数据收发。通过 connect 建立连接,write_all 发送数据,read 循环读取响应直到对端关闭或读取超时。设置读取超时时间为5秒,避免客户端无限阻塞。

代码实现

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

fn main() -> io::Result<()> {
    // 目标服务器地址与端口(可修改为实际测试地址)
    let server_addr = "127.0.0.1:8080";
    let message = b"Hello from TCP client!";

    // 1. 连接服务器
    let mut stream = TcpStream::connect(server_addr)?;
    println!("[客户端] 已连接服务器: {}", server_addr);

    // 2. 设置读取超时(5秒)
    stream.set_read_timeout(Some(Duration::from_secs(5)))?;

    // 3. 发送数据
    stream.write_all(message)?;
    println!("[客户端] 已发送 {} 字节数据", message.len());

    // 4. 接收服务器响应
    let mut buffer = [0u8; 1024];
    let mut response = Vec::new();

    loop {
        match stream.read(&mut buffer) {
            Ok(0) => {
                println!("[客户端] 服务器关闭连接");
                break;
            }
            Ok(n) => {
                response.extend_from_slice(&buffer[..n]);
                // 若响应中包含结束标记或长度足够,可提前退出
                if response.len() >= 4096 {
                    break;
                }
            }
            Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
                println!("[客户端] 读取超时(5秒无数据),结束接收");
                break;
            }
            Err(e) => return Err(e),
        }
    }

    // 5. 输出接收到的数据
    if response.is_empty() {
        println!("[客户端] 未收到任何数据");
    } else {
        let text = String::from_utf8_lossy(&response);
        println!("[客户端] 收到 {} 字节数据: {}", response.len(), text);
    }

    Ok(())
}

编译与运行

# 编译
rustc tcp_client.rs -o tcp_client

# 运行(需先启动一个TCP服务器监听 127.0.0.1:8080)
./tcp_client

验证方法

使用 nc(netcat)或任意TCP服务端工具监听本地8080端口进行测试:

# 终端1:启动简易TCP服务器(监听8080端口)
nc -l 127.0.0.1 8080

# 终端2:运行客户端
./tcp_client

预期行为:客户端连接成功后打印“已连接服务器”,发送数据后打印发送字节数;服务器终端会显示收到的消息“Hello from TCP client!”。若服务器手动输入回复内容(如“Hello client!”)并回车,客户端会打印“收到 N 字节数据: Hello client!”。若服务器不回复,客户端在5秒后打印“读取超时”并正常退出。

TCP客户端 TCP服务器 ① TcpStream::connect() ② set_read_timeout(5s) ③ write_all(message) ④ loop { read() } ⑤ 打印响应数据 ① 监听 127.0.0.1:8080 ② accept() 接受连接 ③ read() 接收客户端数据 ④ write() 发送响应 TCP连接建立 发送: "Hello from TCP client!" 响应: 服务器返回数据 5秒无数据 → 超时退出 连接失败 / 发送失败 → 返回错误 地址: 127.0.0.1:8080

判定标准

  • 客户端能成功连接本地监听的服务端,并打印连接成功信息;
  • 服务端能收到客户端发送的原始文本消息,内容与代码中 message 一致;
  • 当服务端主动回复数据时,客户端能完整接收并打印;
  • 当服务端不回复时,客户端在约5秒后打印超时提示并正常退出,无panic;
  • 当服务端未启动时,客户端打印连接错误(Connection refused)并退出,无panic。