How to send raw bytes through a Dart TCP socket

4,828

Obviously it is possible to write bytes without caring about encoding; Google searches however don't yield an immediate answer, probably because nobody else ever posed the question and the function itself has not a glaring name or description.

The Socket class in Dart inherits from the IOSink class, which has the add() method that does exactly what I need it to.

From the documentation:

void add (List<int> data) 

Adds byte data to the target consumer, ignoring encoding.
The encoding does not apply to this method, and the data list is passed directly to the target consumer as a stream event.
This function must not be called when a stream is currently being added using addStream.
This operation is non-blocking. See flush or done for how to get any errors generated by this call.

The data list should not be modified after it has been passed to add.

https://api.dartlang.org/stable/2.0.0/dart-io/Socket-class.html

The correct code is simply

var message = Uint8List(4);
var bytedata = ByteData.view(message.buffer);

bytedata.setUint8(0, 0x01);
bytedata.setUint8(1, 0x07);
bytedata.setUint8(2, 0xFF);
bytedata.setUint8(3, 0x88);

socket.add(message)
Share:
4,828
Maldus
Author by

Maldus

I'm a computer science student at Alma Mater Studiorum university. I look forward to the moment when I'll be able to answer something here; atm I'm just asking.

Updated on December 07, 2022

Comments

  • Maldus
    Maldus over 1 year

    I'm stuck on the dumbest possible hindrance I can think of. I'm developing a flutter app that should send via TCP socket (on a local wifi network) an array of bytes.

    Said bytes are raw and not representative of meaningful characters in any encoding (I have values like 0xFF and so on). My code succesfully connects and sends data by using the socket write method. Unfortunately that method only takes an encoded String as argument, and creating one from char codes botches up my message.

    Here is my code:

    var message = Uint8List(4);
    var bytedata = ByteData.view(message.buffer);
    
    bytedata.setUint8(0, 0x01);
    bytedata.setUint8(1, 0x07);
    bytedata.setUint8(2, 0xFF);
    bytedata.setUint8(3, 0x88);
    
    socket.write(String.fromCharCodes(message))
    

    while 0x01 and 0x07 are received correctly, 0xFF and 0x88 get turned into a couple of other bytes, 0xC3BF and 0xC287 (checked with netcat -l 8080 | hexdump command).

    I've googled for a while now for a way to send raw bytes without encoding them as strings, but couldn't find anything. Is it simply not contemplated? I realize Flutter and Dart are meant for high level web development, but it seems absurd to me.

  • Ethan K
    Ethan K about 4 years
    Thank you. This is still relevant in 2020. As much as I enjoy developing in Flutter - the hot reloads, easy state management, etc.. it still lackes major low level features and proper documentation. I reached this section of Socket after attempting to wrok with RawServerSocket and RawSocket. Unfortunately the examples I found were not helpful. This answer gave me a great alternative, it really should be reaching the main page - thank you.
  • AMK
    AMK about 3 years
    You saved my time! Thnx a lot!