Search code examples
c++flutterdarttcp

Send 4bytes floating point value through tcp From Dart to C++


I have a trouble with sending 4 bytes double value through tcp socket from Dart client to c++ server.

Below is flutter(Dart) code.

class DataPacket extends object{
  String message = "some";
  int ID = 1;
  double x = 1.38;

  @override
  String toString() {
    String value = message;
    value += getCharCodeStringFromInt(ID);
    value += getCharCodeStringFromDouble(x);
    return value;
  }

  Uint8List _getInt16LittleEndianBytes(int value) =>
    Uint8List(2)..buffer.asByteData().setInt16(0, value, Endian.little);

  String getCharCodeStringFromInt(int value){
     Uint8List message_id_list = _getInt16LittleEndianBytes(value);
     return getCharCodeStringFromUint8List(message_id_list);
  }

  String getCharCodeStringFromDouble(double value) {
//    List<double> temp = List<double>() ;
//    temp.add(value);
//    Float32List floatlist = Float32List.fromList(temp);
//    Uint8List list = Uint8List.view(floatlist.buffer);

//    Uint8List list = binaryCodec.encode(value);

      Uint8List list = Uint8List(4)..buffer.asByteData().setFloat32(0, value);

      print("Uint8List from double : ${list}");
      print("Uint8List length from double : ${list.length}");
      print("CharCodeString from double Length : 
      ${getCharCodeStringFromUint8List(list).length}");
      return getCharCodeStringFromUint8List(list);
  }

  String getCharCodeStringFromUint8List(Uint8List list){
    String charCodeString = "";
    list.forEach((charCode) => charCodeString += String.fromCharCode(charCode));
    return charCodeString;
  }

}


//Some Class   
void sendMessage(){
  print(DataPacket().toString().length);
  List<int> data = _socket.encoding.encode(DataPacket().toString());
                   //utf8.encode(DataPacket().toString());
  print(data.length);
  _socket.add(data);
}

I can parse String and int in c++ by memcpy. but can't double value.

When I checked the contents of Byte Data and Length, Uint8List that was gotten from double has lengthened in encoding method of socket.

I mean, length of Uint8List from double was 4 before encoded. However length of return value(List) becomes 7 after encoding. so print result of DataPacket().toString().length and data.length is different each other.

I can't parse 7 bytes of float in c++..

Commented lines are ways I tried.

Is there any way?

Thank you.


Solution

  • The problem isn't how you are encoding the float as bytes, but rather what you do to it next trying to convert it to a string.

    If you want to send 4 bytes through the socket (assuming you are referring to a dart:io Socket), just use the add method.

      Socket s;
      var floatValue = 1.38;
      var bytes = Uint8List(4)
        ..buffer.asByteData().setFloat32(0, floatValue, Endian.little);
      print(bytes); // prints [215, 163, 176, 63]
      s.add(bytes);
    

    In this example, you've started with the target byte array and then used it asByteData to set one value. This is a good way to build up a struct of mixed types - ints, floats, etc. If you just need to convert an array of floats to bytes you can do it slightly more simply with:

      var bytes = Float32List.fromList([floatValue]).buffer.asUint8List();
    

    I'm not sure you really need to be doing anything with strings. Is what you really want:

      Socket s;
      var message = 'some';
      var id = 1;
      var x = 1.38;
    
      s.add(ascii.encode(message)); // choose the appropriate codec: ascii, utf8
      s.add(Int16List.fromList([id]).buffer.asUint8List());
      s.add(Float32List.fromList([x]).buffer.asUint8List());
      // rather than adding each in turn, you could also form a longer byte array
      // of the 3 elements and add that