3

I am trying to make a echo server that capitalize a String when it replies, to practice with tokio as an exercise. I used an array as a buffer which is annoying because what if the string overflows the buffer?

I would like to know if there is a better way to this without using an array, ideally just using a String or a vector without needing to create the buffer array.

I tried read_from_string() but is not async and ends up blocking the socket.

extern crate tokio;
use tokio::net::TcpListener;
use tokio::prelude::*;

fn main() {
    let addr = "127.0.0.1:6142".parse().unwrap();
    let listener = TcpListener::bind(&addr).unwrap();

    let server = listener
        .incoming()
        .for_each(|socket| {

            let (mut reader, mut writer) = socket.split();
            let mut buffer = [0; 16];
            reader.poll_read(&mut buffer)?;

            let s = std::str::from_utf8(&buffer).unwrap();
            s.to_uppercase();
            writer.poll_write(&mut s.as_bytes())?;

            Ok(())
        })
        .map_err(|e| {
            eprintln!("something went wrong {}", e);
        });

    tokio::run(server);
}

Results: "012345678901234567890" becomes -> "0123456789012345"

I could increase the buffer of course but it would just kick the can down the road.

lucarlig
  • 141
  • 3
  • 12
  • did you just try to use a string ? Also, it's better on server to limit memory allocation from client – Stargateur May 16 '19 at 03:15
  • @Stargateur yes I coulnd't make it compile. Interesting makes total sense, do you know where can i find more info about this kind of design decisions on server programming? Book or whatever. – lucarlig May 16 '19 at 03:27

1 Answers1

1

I believe tokio_codec is a right tool for such tasks. Tokio documentation: https://tokio.rs/docs/going-deeper/frames/

It uses Bytes / BytesMut as its buffer - very powerful structure which will allow you to process your data however you want and avoid unnecessary copies

Laney
  • 1,571
  • 9
  • 7