Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

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

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:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

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

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading