Read TCPStream into structure

Hi,

I want to read some TCPStream bytes into structure, I tried to read into bytes and then converted into structure. Now, facing some challenges.

let mut message = TReqMobileBinHandshake{
m_length: 0,
m_type: 0,
m_version: 0,
m_ip: 0,
m_sendDelay: 0,
m_sendFrequency: 0
};

let mut data = [0;20];

while match stream.read(&mut data) {
    Ok(size) => {
        // echo everything!
        //let message: TReqMobileBinHandshake = &data;
        //let text = from_utf8(&data).unwrap(); = 
        **message =  unsafe { mem::transmute::<[u8; 20],  std::mem::size_of::<TReqMobileBinHandshake>()>(data) };**
        println!("Message received: {}, {}", message.m_length, message.m_sendFrequency);
        //stream.write(&data[0..size]).unwrap();
        true
    },
    Err(_) => {
        println!("An error occurred, terminating connection with {}", stream.peer_addr().unwrap());
        stream.shutdown(Shutdown::Both).unwrap();
        false
    }
} 

Getting below error:

error[E0747]: constant provided when a type was expected
--> src\main.rs:41:61
|
41 | message = unsafe { mem::transmute::<[u8; 20], mem::size_of::()>(data) };

What the compiler is pointing out is that std::mem::transmute() takes 2 generic type parameters.
Your code is trying to use std::mem::size_of() as a type argument, which can never work, as fns return values, not types.

In addition to that, trying to transmute a byte array into a type seems like one of those things that could easily lead to UB. I for one don't know this is sound, and if I saw this in a code base I would regard it as fairly sus code.

Be aware that stream.read() may well return with less than the number of bytes than would fill your data buffer. Which is why it returns the number of bytes actually read. Your code would produce surprisingly wrong results if the buffer were not filled by read(). Use stream.read_exact() to be sure the buffer is filled.

I too would be wary of transmuting bytes into a structure. What if the machine you are running stores the bytes of integers in the reverse order? Endianness - Wikipedia

Better to parse your bytes into the required integers and whatever and put those into your struct. I'm sure there is are creates out there to help with such deserialisation.

By the way, what is with all m_ ? Is this necessary given that it is always preceded by message. when used?

1 Like

GitHub - sharksforarms/deku: Declarative binary reading and writing: bit-level, symmetric, serialization/deserialization makes this action pretty simplistic.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.