UDP not received data correct.. Where wrong?

Ok guys, I need to convert a JavaScript to XoJo code !
I have to do it somehow.

LET’S GO.

I have this JavaScript (it run by Node.js) that it work very fine (100% tested):

const PORT = 49000;
const HOST = '127.0.0.1';
const FREQ = 1;
const dgram = require('dgram');
const client = dgram.createSocket('udp4');

const createMessage = (dref, idx, freq) => {
    const message = Buffer.alloc(413);
    message.write('RREF\0');
    message.writeInt8(freq, 5);
    message.writeInt8(idx, 9);
    message.write(dref, 13);
    return message;
};

const messages = [
    createMessage('sim/flightmodel/position/latitude', 1, FREQ),
    createMessage('sim/flightmodel/position/longitude', 1, FREQ),
    createMessage('sim/flightmodel/position/mag_psi', 1, FREQ),
];

client.on('listening', () => {
    const address = client.address();
});

client.on('message', (message, remote) => {
    const label = message.toString('utf8', 0, 4);
    if (label == 'RREF') {
        let offset = 9;
        let messages = [];
        while (offset < message.length) {
            const value = message.readFloatLE(offset);
            messages.push(value);
            offset += 8;
        }
        var fs = require("fs");
        var data = new Buffer.from(messages[0] + "@" + messages[1]);
        fs.writeFile(process.env.APPDATA + "/MYDIR/OUT.txt", data, (err) => {
         });
         //console.log("Saved.");
    }
});

for (let i = 0; i < messages.length; i++) {
    client.send(messages[i], 0, messages[i].length, PORT, HOST, (err, bytes) => { });

}

OK. NOW I CONVERT TO XOJO:


  1. I have a “UDPSocket” (namedUDPSocket1) in Window1
  2. I have the event “DataAvaiable” in UDPSocket1
  3. In a PushButton.Action I have a code

Code in PushButton.Action:

Var mb As New MemoryBlock(413)
mb.StringValue(0,5) = "RREF"
mb.Int8Value(5) = 1
mb.Int8Value(9) = 1
mb.StringValue(13,400) = "sim/flightmodel/position/latitude"

Window1.UDPSocket1.Port = 49000
Window1.UDPSocket1.Connect
If UDPSocket1.IsConnected Then MessageBox("Is Connected")
Window1.UdPSocket1.Write("127.0.0.1", mb.StringValue(0,413) ) //Send the message to XPlane11 from 49000 port

Code in “DataAvaiable” event in UDPSocket1

Dim data As Datagram = Me.Read
Label1.Text = data.Data

But I not received the correct data struct.
I received this:

instead of
0@43.80808639526367

Considerations ?
What could I be wrong?

Regards.

Surely you’re getting exactly the expected data, namely, the data you’ve sent out. You’re writing to yourself.

127.0.0.1 is LocalHost, i.e., your own machine.

What you received is exactly what you sent. What did you intend to send?

You need to do this on 2 different computers in the network not 127.0.0.1 on both sides that won’t really work. Your just receiving send to self probably now.
You can set send to self off. (This may not always turn it actually off)

Hi,
the situation is:

  • XPlane11 is run in my PC
  • node.js (javascript) is run in my PC

When javascript run from Terminal Windows10 (C:\Users…\node RecData.js), this javascript work fine and it write to a file two data: latitude and longidude.
The file conteins this: 43.80808639526367@11.196493148803711
and is correct.
(If you look carefully my first post, in reality the data would be three, but for the test with you I am only using latitude and longitude; mag_psi do not consider it.)

Therefore the two programs (JavaScript by Node.js and XPlane11) communicate with each other from the same PC.

The first consideration to be made is the NULL character:
In javascript, ‘\0’ is used.
In Xojo I use Chr (0).
Here (link) you can read the HowTo of Austin (the XPlane programmer).
Is a TXT file, and there are two parts that must interest me:

  • the first page up to GET STARTED
  • and only SEND ME ALL THE DATAREFS I WANT: RREF
    Here you can understand how it works. It is very simple.

Here (link) my xojo project for this little test.

I believe I have given you everything you need to help me. I don’t know where to turn my head anymore :wink:
Obviously, thank you in advance for your availability.

In your javascript you have:

client.on('message', (message, remote) => {
    const label = message.toString('utf8', 0, 4);
    if (label == 'RREF') {
        let offset = 9;
        let messages = [];
        while (offset < message.length) {
            const value = message.readFloatLE(offset);
            messages.push(value);
            offset += 8;
        }
        var fs = require("fs");
        var data = new Buffer.from(messages[0] + "@" + messages[1]);
        fs.writeFile(process.env.APPDATA + "/MYDIR/OUT.txt", data, (err) => {
         });
         //console.log("Saved.");
    }
});

This contains code to use the incoming data and do something with it before writing to OUT.txt.

Where is the Xojo equivalent of the code to do something with the data? It’s not in the DataAvailable event.

1 Like

Hi Tim Streater,
Let’s take it one step at a time.

First step
I would like to know: when Xojo UDPSocket receives the message from XPlane, I believe who should use the “DataAvailable” event. That’s right ?

Second step
Consequently, in the DataAvailable event:

Dim data As Datagram = Me.Read
Label1.Text = data.Data

I have to find a string that, with XoJo debugging, I go to read to understand what XPlane is sending me.
For now, it does not matter to decrypt the received Datagram: I am interested in seeing the whole message which will be composed as follows: “RREF” + 8byte for each message sent to XPlane.
While I only receive what I send to XPlane, that is: RREF + 1 + 1 + sim / flightmodel / position / latitude (See image of my first post).

So I ask myself: If the first step is correct, how can I know if the message received comes from XPlane?

This is my first time using sockets, so be patient :innocent:

I’ve not used UDPsockets so I don’t know whether two applications on the same machine can connect to the same port. But, assuming they can, I would expect that if an app sends to LocalHost, then it will see its own packets coming back to it. So perhaps your Xojo app will have DataAvailable twice, once for its own data and once for the Xplane11 response.

You can prevent the bounce-back messages by setting the SendToSelf property to False.

Hmmm, I thought the doc said that only applies to multicast.

I also tried UDPSocket1.SendToSelf = False , but not work.

UDPSocket1.Port = 49000
UDPSocket1.SendToSelf = False
UDPSocket1.Connect
If UDPSocket1.IsConnected Then MessageBox("Is Connected")

UDPSocket1.Write("192.168.1.100", "RPOS" + Chr(0) + "60" + Chr(0) )

I tried to send another type of simpler message (to understand if the problem was due to the message that was not correct), but nothing to do. I keep getting the usual message that I send to XPlane11.

Here the doc from XPlane11:
••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••
JUST LET ME GET OUTPUT FROM X-PLANE TO DRIVE MY VISUAL OR MAP: RPOS
••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••

Now: A UDP output from X-Plane to drive you own visuals or moving map!

Send the following data to X-Plane’s IP address by UDP into port 49,000:

The 5 chars “RPOS” (four chars plus a NULL at the end!) followed by a STRING (also null-terminated of course!) that lists the number of positions per second that you want X-Plane to send right back to you
to drive your visual system.
So send “RPOS_60_”, where the _ is a null, to have X-Plane send you it’s position 60 times per second.

NOTE: X-Plane will send the message right back to the IP address and port number you sent the RPOS command FROM!

This is in the settings menu, internet settings screen, right-most tab for data output.

And here is the data that will come to you, with no annoying struct-alignment issues: The data is all perfectly tightly packed with no spacing.

the four chars RPOS and a NULL.
double dat_lon longitude of the aircraft in X-Plane of course, in degrees
double dat_lat latitude
double dat_ele elevation above sea level in meters
float y_agl_mtr elevation above the terrain in meters
float veh_the_loc pitch, degrees
float veh_psi_loc true heading, in degrees
float veh_phi_loc roll, in degrees
float vx_wrl speed in the x, EAST, direction, in meters per second
float vy_wrl speed in the y, UP, direction, in meters per second
float vz_wrl speed in the z, SOUTH, direction, in meters per second
float Prad roll rate in radians per second
float Qrad pitch rate in radians per second
float Rrad yah rate in radians per second

So, this is very simple, and will let you drive your moving maps and external visuals, which is the most commonly used output from X-Plane!

Uffffffh, I feel like giving up.

Since the other app is on the same computer, have Xojo send/listen from a different port and so you do not get the your own data back:

UDPSocket1.Port = 49001  // my port to send/listen
UDPSocket1.SendToSelf = False
UDPSocket1.Connect
If UDPSocket1.IsConnected Then MessageBox("Is Connected")

To send to the correct port (49000) you need to use a datagram, which lets you specify the destination IP and Port:

var dg as Datagram
dg.Address = "192.168.1.100" // destination address
dg.Port = 49000 // their port
dg.Data = "RPOS" + Chr(0) + "60" + Chr(0)
UDPSocket1.Write(dg)

You may want to lower the frequency, 60 per second is a LOT of data.