I'm new to rust and I've been trying things to learn. I've created a TCP client script and a TCP server. First I tried just makeing a conection between both of them and I did and now I want to send a file from the client to the server. In the client i create and write the file but i get an error when I send it.
This is the error I get: Error
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)
Here I add both scripts, first the client and then the server:
// 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);
}
}
}
}
As I mentioned earlier I'm starting with this language so I'm sure there are better ways to do this but as I still do not understand many concepts I'm trying to make it simple, or that is what I think.
The problem is that File::create
Opens a file in write-only mode.
So to read from it you can simply reopen it in read mode:
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();
write_file(&file).unwrap();
let mut file = File::open("file01.txt").unwrap();
let mut buffer_send = Vec::new();
file.read_to_end(&mut buffer_send).unwrap();
//…
}
Alternatively you can open the file in read and write mode with OpenOptions
to begin with:
use std::fs::OpenOptions;
fn create_file() -> std::io::Result<File> {
OpenOptions::new()
.read(true)
.write(true)
.truncate(true)
.create(true)
.open("file01.txt")
}
But then have to rewind in between writing and reading to see the new content:
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();
file.rewind().unwrap();
let mut buffer_send = Vec::new();
file.read_to_end(&mut buffer_send).unwrap();
//…
}