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
相关产品推荐
相关产品推荐

