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