You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rust实现TCP客户端向服务器传文件遇权限拒绝错误求助

解决Rust TCP客户端文件发送权限拒绝错误

问题场景

用Rust实现TCP客户端向服务器发送文件,客户端创建并写入文件后,发送阶段触发权限拒绝错误,错误信息如下:

cargo run
   Compiling tcp_client v0.1.0 (C:\Proyectos\Rust_TCP\File_transfer\tcp_client)
    Finished dev [unoptimized + debuginfo] target(s) in 1.03s
     Running `target\debug\tcp_client.exe`
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Os { code: 5, kind: PermissionDenied, message: "Acceso denegado." }', src\main.rs:24:40
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
error: process didn't exit successfully: `target\debug\tcp_client.exe` (exit code: 101)

客户端代码

// Client TCP
use std::io::{Read, Write};
use std::net::{TcpStream};
use std::fs::File;

fn create_file() -> std::io::Result<File>{
    let file = File::create("file01.txt")?;
    Ok(file)
}

fn write_file(mut file: &File) -> std::io::Result<&File>{
    const CONTENT: &str = "This is a text file for the server.";
    file.write_all(CONTENT.as_bytes())?;
    Ok(file)
}

fn main() {
    // Write and send
    let mut stream = TcpStream::connect("127.0.0.1:7070").expect("Failed to connect to server.");
    let file = create_file().unwrap();
    let mut file = write_file(&file).unwrap();
    let mut buffer_send = Vec::new();
    file.read_to_end(&mut buffer_send).unwrap();

    stream.write_all(&buffer_send).expect("Failed to send file to server");

    // Read answer
    let mut buffer = [0; 512];
    let bytes_readed = stream.read(&mut buffer).expect("Failed to read from server.");
    let response = String::from_utf8_lossy(&buffer[..bytes_readed]);

    println!("Message from server: {}", response);
}

服务器代码

// Server TCP
use std::io::{Read, Write};
use std::net::{TcpListener, TcpStream};

fn handle_client(mut stream: TcpStream) {
    let mut buffer = [0; 1024];
    let size = stream.read(&mut buffer).unwrap();
    let file_content = &buffer[..size];
    let file_string = String::from_utf8_lossy(file_content);
    println!("Contenido del archivo recibido:\n{}", file_string);
    let response = b"File received";
    stream.write_all(response).unwrap();
}

fn main() {
    let listener = TcpListener::bind("127.0.0.1:7070").unwrap();

    for stream in listener.incoming() {
        match stream {
            Ok(stream) => {
                println!("Client connected");
                handle_client(stream);
            }
            Err(e) => {
                println!("Failed accepting connection: {}", e);
            }
        }
    }
}

错误原因

File::create("file01.txt")默认以只写模式打开文件,没有读取权限,后续调用read_to_end时会触发权限拒绝错误。

解决方案

方案1:创建文件时同时指定读写权限

使用OpenOptions显式设置创建、写入、读取权限:

修改客户端的create_file函数:

use std::fs::OpenOptions;

fn create_file() -> std::io::Result<File>{
    let file = OpenOptions::new()
        .create(true)
        .write(true)
        .read(true)
        .open("file01.txt")?;
    Ok(file)
}

方案2:写入后关闭文件,重新以读模式打开

写入完成后关闭文件句柄,再重新打开读取:

修改客户端main函数:

fn main() {
    let mut stream = TcpStream::connect("127.0.0.1:7070").expect("Failed to connect to server.");
    
    // 创建并写入文件
    let file = create_file().unwrap();
    write_file(&file).unwrap();
    // 关闭文件句柄
    drop(file);
    
    // 重新以读模式打开
    let mut file = File::open("file01.txt").unwrap();
    let mut buffer_send = Vec::new();
    file.read_to_end(&mut buffer_send).unwrap();

    stream.write_all(&buffer_send).expect("Failed to send file to server");

    // 读取服务器响应
    let mut buffer = [0; 512];
    let bytes_readed = stream.read(&mut buffer).expect("Failed to read from server.");
    let response = String::from_utf8_lossy(&buffer[..bytes_readed]);

    println!("Message from server: {}", response);
}

方案3:简化代码逻辑(推荐)

直接将内容存入内存发送,无需写入后再读取文件,减少IO操作:

修改客户端代码:

fn main() {
    let mut stream = TcpStream::connect("127.0.0.1:7070").expect("Failed to connect to server.");
    
    const CONTENT: &str = "This is a text file for the server.";
    // 直接使用内容字节数组发送
    stream.write_all(CONTENT.as_bytes()).expect("Failed to send file to server");

    // 读取服务器响应
    let mut buffer = [0; 512];
    let bytes_readed = stream.read(&mut buffer).expect("Failed to read from server.");
    let response = String::from_utf8_lossy(&buffer[..bytes_readed]);

    println!("Message from server: {}", response);
    
    // 如需保留本地文件,单独写入
    let _ = File::create("file01.txt").unwrap().write_all(CONTENT.as_bytes());
}

验证

修改后重新运行cargo run,客户端将成功发送文件内容到服务器,服务器正常接收并返回响应。

内容的提问来源于stack exchange,提问作者Linux

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 19:35:06