Write_all and read using framed ... Not working Sending file over the network

Hi
I have a file that is formatted as fstrm . I have a method that reads the file and writes into the socket using write_all . This seems to be working as expected .

On the server side I have a method that tries to read this using framed Read and this is obviously not working since I am assuming the Codec is different .

Is there an equivalent read_all from socket that can be help this async read ?

server side code


async fn process(stream: TcpStream) -> Result<(), Box<dyn Error>> {
    let mut framed = BytesCodec::new().framed(stream);
    let mut count=0; // # of packets. 1st is Control
    while let Some(request) = framed.next().await {
        match request {
            Ok(request) => {
                println!(" received: {:?}",request);
                //dns_decode(request.freeze(),count);
                //count+=count+1;
            }
            Err(e) => return Err(e.into()),
        }
    }
    println!("Connection closed");

    Ok(())
}

Client Side Code


fn main() -> io::Result<()> {
    let filename = env::args()
        .nth(1)
        .unwrap_or_else(|| "dnstap.log".to_string());

    let addr = env::args()
        .nth(2)
        .unwrap_or_else(|| "127.0.0.1:8080".to_string());

    println!("Connecting to {:?} to send file {:?}",addr,filename);

    let buffer = std::fs::read(filename)?;
    let buf1 = Bytes::from(buffer);
    let mut tcp = TcpStream::connect(addr)?;

    let mut current_pointer: usize = 42;
    let mut data_frame_length:u32 = 0;
    let data_field_size: usize = 4;
    tcp.write_all(&buf1[0 .. current_pointer])?;  // Write the first 42 bytes which is the header on connect .
    loop {

        data_frame_length = u32::from_be_bytes(
            buf1[current_pointer..(current_pointer + data_field_size)]
                .try_into()
                .unwrap(),
        );
        println!("Current Pointer {:?}, Next Data frame length = {}", current_pointer,data_frame_length);
        if data_frame_length == 0 {
            break;
        }
        //let mut data_frame = &buf1[current_pointer..(current_pointer + data_frame_length as usize)];
        tcp.write_all(&buf1[current_pointer..(current_pointer + data_field_size +  data_frame_length as usize)]);
        current_pointer += data_field_size;
        current_pointer += data_frame_length as usize;
    }

    Ok(())
}

Can you please fix your formatting?

Done. Sorry I was using and . I have replaced that with 3 backticks. Thanks

What does "not working" means? It prints data different from what was sent?

The client seems to send the data in the correct format .

The server receives a lot more data . I guess i need to do "Framing" while receiving . Any ideas on how this can be done ?

I hit upon the LenghtDelimitedCodec of Tokio Length Delimited Codec /

But I have a problem since my 2 frames have different formats .
1st format is 4 bytes -- zero and 2nd 4 bytes is the length

2nd format is 4 bytes --> length followed by data .

(i.e.) Any idea how I can use the length field len to be able to read ?

 |------------------------------------|----------------------|
# | Data frame length                  | 4 bytes              |  
# |------------------------------------|----------------------|
# | Control frame length               | 4 bytes              |
# |------------------------------------|----------------------|
# | Control frame type                 | 4 bytes              |
# |------------------------------------|----------------------|
# | Control frame content type         | 4 bytes (optional)   |
# |------------------------------------|----------------------|
# | Control frame content type length  | 4 bytes (optional)   |
# |------------------------------------|----------------------|
# | Content type payload               | xx bytes             |     
# |------------------------------------|----------------------|

# Frame Streams Data Frame Format

# |------------------------------------|----------------------|
# | Data frame length                  | 4 bytes              |
# |------------------------------------|----------------------|
# | Payload - Protobuf                 | xx bytes             |
# |------------------------------------|----------------------|

 Control Frame is  data_frame_length

It sounds like you would have to write your own codec here. The documentation here should explain how to do so. Adapting the example decoder should be rather easy, since it's already length-based.

Note that your link is to a very old version of tokio_util.