upload/download from stdin/stdout
This commit is contained in:
parent
3118726d81
commit
d35d4ee0c1
|
@ -5,7 +5,8 @@ extern crate tokio;
|
||||||
extern crate thiserror;
|
extern crate thiserror;
|
||||||
|
|
||||||
use hptp::log::Logger;
|
use hptp::log::Logger;
|
||||||
// use tokio::net::UdpSocket;
|
use tokio::io::{AsyncWriteExt, Stdout};
|
||||||
|
use tokio::net::UdpSocket;
|
||||||
|
|
||||||
#[derive(Error, Debug)]
|
#[derive(Error, Debug)]
|
||||||
enum Error {
|
enum Error {
|
||||||
|
@ -40,15 +41,17 @@ async fn start(log: &mut Logger) -> Result<(), Error> {
|
||||||
.await
|
.await
|
||||||
.map_err(|_| Error::NoPortAvail)?;
|
.map_err(|_| Error::NoPortAvail)?;
|
||||||
log.bound(sock.local_addr()?.port()).await;
|
log.bound(sock.local_addr()?.port()).await;
|
||||||
|
download(log, sock, tokio::io::stdout()).await
|
||||||
|
}
|
||||||
|
|
||||||
let (mut rx, _tx) = sock.split();
|
async fn download(log: &mut Logger, mut sock: UdpSocket, mut out: Stdout) -> Result<(), Error> {
|
||||||
let mut buf = [0u8; 2000];
|
let mut buf = [0u8; 2000];
|
||||||
|
let mut pos = 0;
|
||||||
loop {
|
loop {
|
||||||
let (n, _who) = rx.recv_from(&mut buf).await?;
|
let (len, _who) = sock.recv_from(&mut buf).await?;
|
||||||
log.debug_msg(match String::from_utf8(buf[..n].into()) {
|
out.write_all(&buf[..len]).await?;
|
||||||
Ok(s) => format!("got: {:?}", s),
|
out.flush().await?;
|
||||||
Err(e) => format!("got: {:?} (invalid utf8)", e.as_bytes()),
|
log.recv_data_accepted(pos, len, hptp::log::InOrder).await;
|
||||||
})
|
pos += len;
|
||||||
.await;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,8 @@ extern crate thiserror;
|
||||||
|
|
||||||
use hptp::log::Logger;
|
use hptp::log::Logger;
|
||||||
use std::net::SocketAddrV4;
|
use std::net::SocketAddrV4;
|
||||||
|
use tokio::io::{AsyncReadExt, Stdin};
|
||||||
|
use tokio::net::UdpSocket;
|
||||||
|
|
||||||
#[derive(Error, Debug)]
|
#[derive(Error, Debug)]
|
||||||
enum Error {
|
enum Error {
|
||||||
|
@ -52,7 +54,7 @@ async fn start(log: &mut Logger) -> Result<(), Error> {
|
||||||
.map_err(|_| Error::NoAvailPort)?;
|
.map_err(|_| Error::NoAvailPort)?;
|
||||||
log.debug_msg(format!("bound on {}", sock.local_addr()?))
|
log.debug_msg(format!("bound on {}", sock.local_addr()?))
|
||||||
.await;
|
.await;
|
||||||
upload(log, sock, targ_addr).await?;
|
upload(log, sock, tokio::io::stdin(), targ_addr).await?;
|
||||||
log.debug_msg("bye!").await;
|
log.debug_msg("bye!").await;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -66,24 +68,20 @@ fn parse_args(mut args: impl Iterator<Item = String>) -> Result<SocketAddrV4, Er
|
||||||
|
|
||||||
async fn upload(
|
async fn upload(
|
||||||
log: &mut Logger,
|
log: &mut Logger,
|
||||||
mut sock: tokio::net::UdpSocket,
|
mut sock: UdpSocket,
|
||||||
|
mut inp: Stdin,
|
||||||
targ_addr: SocketAddrV4,
|
targ_addr: SocketAddrV4,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
let contents: String = (0..100).flat_map(|_| "Hello world ".chars()).collect();
|
let mut buf = [0u8; 500];
|
||||||
|
let mut pos = 0;
|
||||||
for i in 0.. {
|
loop {
|
||||||
let (idx, part) = {
|
let len = inp.read(&mut buf).await?;
|
||||||
let width = 50;
|
if len == 0 {
|
||||||
let lo = i * width;
|
break;
|
||||||
let hi = std::cmp::min((i + 1) * width, contents.len());
|
}
|
||||||
if lo >= contents.len() {
|
sock.send_to(&buf[..len], targ_addr).await?;
|
||||||
break;
|
log.send_data(pos, len).await;
|
||||||
};
|
pos += len;
|
||||||
(lo, &contents[lo..hi])
|
|
||||||
};
|
|
||||||
sock.send_to(part.as_bytes(), targ_addr).await?;
|
|
||||||
log.send_data(idx, part.len()).await;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue