(rust) file transfer via tcp
added lorem.md for tests
This commit is contained in:
+68
-8
@@ -1,7 +1,5 @@
|
|||||||
#![allow(dead_code, unused)]
|
#![allow(dead_code, unused)]
|
||||||
|
|
||||||
use std::fs::read;
|
|
||||||
|
|
||||||
use chrono::{
|
use chrono::{
|
||||||
DateTime,
|
DateTime,
|
||||||
Local,
|
Local,
|
||||||
@@ -42,21 +40,20 @@ use tokio::{
|
|||||||
async fn main() -> anyhow::Result<()> {
|
async fn main() -> anyhow::Result<()> {
|
||||||
let listener = TcpListener::bind("127.0.0.1:9090").await?;
|
let listener = TcpListener::bind("127.0.0.1:9090").await?;
|
||||||
|
|
||||||
let file = fs::read("test.md").await?;
|
let file = fs::read("../lorem.md").await?;
|
||||||
|
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
sleep(Duration::from_secs(2)).await;
|
sleep(Duration::from_secs(1)).await;
|
||||||
|
|
||||||
let mut connection = TcpStream::connect("127.0.0.1:9090").await.unwrap();
|
let mut connection = TcpStream::connect("127.0.0.1:9090").await.unwrap();
|
||||||
connection.write_all(&file[..]).await.unwrap();
|
_ = send_file(&mut connection, file).await;
|
||||||
});
|
});
|
||||||
|
|
||||||
let mut read_buffer = [0u8; 2<<16];
|
|
||||||
match listener.accept().await {
|
match listener.accept().await {
|
||||||
Ok((mut stream, address)) => {
|
Ok((mut stream, address)) => {
|
||||||
println!("accepted connection request from {}", address);
|
println!("accepted connection request from {}", address);
|
||||||
let size = stream.read(&mut read_buffer).await?;
|
let file = receive_file(&mut stream).await?;
|
||||||
fs::write("test-copy.md", &read_buffer[0..size]).await?;
|
fs::write("test-lorem.md", file).await?;
|
||||||
}
|
}
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
println!("this is unexpected.. {}", error.to_string());
|
println!("this is unexpected.. {}", error.to_string());
|
||||||
@@ -66,4 +63,67 @@ async fn main() -> anyhow::Result<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn receive_file(stream: &mut TcpStream) -> Result<Vec<u8>, anyhow::Error> {
|
||||||
|
const BUFFER_SIZE: usize = 4096;
|
||||||
|
let mut buffer = [0u8; BUFFER_SIZE];
|
||||||
|
let mut index_counter: usize = 0;
|
||||||
|
let mut processing_buffer = Vec::<u8>::new();
|
||||||
|
let mut file = Vec::<u8>::new();
|
||||||
|
let mut size: usize = 0;
|
||||||
|
|
||||||
|
loop {
|
||||||
|
let num_bytes = stream.read(&mut buffer[..]).await?;
|
||||||
|
processing_buffer.extend(&buffer[0..num_bytes]);
|
||||||
|
if 0 == index_counter {
|
||||||
|
size = usize::from_be_bytes(processing_buffer.drain(0..8).collect::<Vec<_>>().try_into().unwrap());
|
||||||
|
} else {
|
||||||
|
_ = processing_buffer.drain(0..8);
|
||||||
|
}
|
||||||
|
let block_size = usize::from_be_bytes(processing_buffer.drain(0..8).collect::<Vec<_>>().try_into().unwrap());
|
||||||
|
let index = usize::from_be_bytes(processing_buffer.drain(0..8).collect::<Vec<_>>().try_into().unwrap());
|
||||||
|
|
||||||
|
if index_counter != index {
|
||||||
|
panic!("meh, counter = {index_counter}, index = {index}");
|
||||||
|
}
|
||||||
|
|
||||||
|
file.extend(processing_buffer.drain(0..block_size));
|
||||||
|
|
||||||
|
index_counter += 1;
|
||||||
|
if block_size >= size {
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
size -= block_size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(file)
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn send_file(stream: &mut TcpStream, mut file: Vec<u8>) -> Result<(), anyhow::Error> {
|
||||||
|
const BLOCK_SIZE: usize = 2048;
|
||||||
|
let size: usize = file.len();
|
||||||
|
let mut remaining = size;
|
||||||
|
let mut index: usize = 0;
|
||||||
|
|
||||||
|
while remaining > 0 {
|
||||||
|
let mut block = Vec::<u8>::new();
|
||||||
|
let len = if remaining >= BLOCK_SIZE {
|
||||||
|
BLOCK_SIZE
|
||||||
|
} else {
|
||||||
|
remaining
|
||||||
|
};
|
||||||
|
|
||||||
|
block.extend(size.to_be_bytes());
|
||||||
|
block.extend(len.to_be_bytes());
|
||||||
|
block.extend(index.to_be_bytes());
|
||||||
|
block.extend(file.drain(0..len));
|
||||||
|
|
||||||
|
stream.write(&block[..]).await?;
|
||||||
|
|
||||||
|
remaining -= len;
|
||||||
|
index += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user