1. TCP回显服务器

TCP回显服务器 学习卡片

任务说明

实现一个基于TCP的简单回显服务器:监听本地端口,接受客户端连接,将收到的每条消息原样返回给客户端。客户端发送quit时关闭该连接,服务器收到Ctrl+C时优雅退出。

代码实现

use std::io::{Read, Write};
use std::net::{TcpListener, TcpStream};
use std::thread;

fn handle_client(mut stream: TcpStream) {
    let mut buf = [0u8; 1024];
    loop {
        match stream.read(&mut buf) {
            Ok(0) => {
                // 客户端关闭连接
                println!("连接关闭: {}", stream.peer_addr().unwrap());
                break;
            }
            Ok(n) => {
                let msg = String::from_utf8_lossy(&buf[..n]);
                let trimmed = msg.trim();
                println!("收到: {}", trimmed);

                // 原样返回(保留原始字节,不做trim)
                if stream.write_all(&buf[..n]).is_err() {
                    break;
                }

                // 收到 quit 则关闭连接
                if trimmed == "quit" {
                    println!("客户端请求退出");
                    break;
                }
            }
            Err(e) => {
                eprintln!("读取错误: {}", e);
                break;
            }
        }
    }
}

fn main() -> std::io::Result<()> {
    let addr = "127.0.0.1:8080";
    let listener = TcpListener::bind(addr)?;
    println!("回显服务器监听于 {}", addr);

    for stream in listener.incoming() {
        match stream {
            Ok(stream) => {
                println!("新连接: {}", stream.peer_addr().unwrap());
                thread::spawn(|| handle_client(stream));
            }
            Err(e) => eprintln!("连接失败: {}", e),
        }
    }
    Ok(())
}

运行与验证

依赖:仅需Rust标准库,无需外部crate。

运行服务器:

rustc echo_server.rs && ./echo_server

验证方法:另开终端,使用nc或telnet连接测试:

nc 127.0.0.1 8080

输入任意文本(如hello),服务器应原样返回该文本;输入quit后连接关闭。服务器终端会依次打印收到的消息和连接事件。

判定标准:

  • 客户端发送hello,收到回复hello,即回显功能正常;
  • 发送quit后连接断开,服务器无报错;
  • 多个客户端可同时连接且互不影响(每连接独立线程处理)。
TCP回显服务器 连接时序 客户端 (nc/telnet) 服务器 (echo_server) TCP连接 (127.0.0.1:8080) 发送: "hello" 回显: "hello" 发送: "quit" 回显: "quit" 服务器检测到 "quit",关闭连接 每连接独立线程 · 原样返回字节 · "quit"触发关闭

代码说明

服务器使用TcpListener绑定127.0.0.1:8080,通过incoming()循环接受连接。每个连接由thread::spawn创建独立线程处理,实现并发。处理逻辑为:循环读取最多1024字节,将读取到的原始字节通过write_all原样写回;若读取到0字节(客户端关闭)或收到quit命令则退出循环。主线程持续监听新连接,直到进程被终止。