How to send a file from a tcp client to a server

Advertisements

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.

>Solution :

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();
    //…
}

Leave a ReplyCancel reply