B4J Question [Solved] UDP packet data as objects B4J <> B4R using B4RSerializator

KiloBravo

Active Member
Licensed User
I am TRYING to send UDP Packets back and forth from a B4J Client to a B4R Server (ESP8266 is the Server ).
The ESP8266 is set to an AP and I connect the B4J client to the ESP8266 SSID which I set. That all works.
I can send from the B4J Client and Receive on the B4R side. Then I take the received Objects and try to sent them back to the B4J Client.
The B4J Client Receives the UDP Packet but I cannot figure out how to decode the Objects from the packet. I control both sides. The data sent from B4J is just an example of what my "real" App might send. I looked at all the examples on the forum but I can't find one for this use case.
Any help decoding the incoming UDP Packet on B4J would be appreciated.
I know their are other "better" solutions, but if anyone can give me pointer on how to get this working that would be great. Thanks !!!

B4R Server Code ...
B4X:
Sub Udp_PacketArrived (Buffer() As Byte, ip() As Byte, port As UInt)
'    Log("PacketArrived ", Buffer.Length," Port= ", port," IP= ",ip(0),".", ip(1),".", ip(2),".", ip(3))
    If Buffer.Length =  0 Then
        Log("Packet Length 0 ")
        Return 'invalid message
    End If
    If Buffer.Length > 50 Then
        Log("Packet Length > 50 ")
        Return 'invalid message
    End If
    '************************************************************
'    Log("Buffer.Length= ",Buffer.Length)
    Dim be(10) As Object 'used as a storage buffer. Can be a global variable
    Dim Data() As Object = serz.ConvertBytesToArray(Buffer, be)
    For Each o As Object In Data
        Log(o)
    Next
    ' Received a Packet Now Send One Back
    Send_Packet(Data)
End Sub

Sub Send_Packet(Data()As Object)
'********************************************************************** 
'''' IP/Port of Client "222.111.7.100" --- "55777"''''''''''''''''''''' 
'********************************************************************** 
    Private ip() As Byte = Array As Byte(222,111,7,100)
    Private port As UInt = 55777 'was 55999
    udp.BeginPacket(ip, port)
    udp.Write(serz.ConvertArrayToBytes(Data))
    udp.SendPacket
    Log("SentPckt")
End Sub

B4J Client Send and Receive Code

B4X:
Sub Button1_Click
    build_Packet
End Sub

Sub build_Packet
    Dim pktStart As Object = "<"
    Dim x As Object = Rnd(0,255)
    Dim y As Object = Rnd(0,255)
    Dim myStr As Object = "string"
    Dim pktEnd As Object = ">"
'
    Dim send_data(5) As Object
    send_data(0) = pktStart
    send_data(1) = x
    send_data(2) = y
    send_data(3) = myStr
    send_data(4) = pktEnd
    udp_SendPacket(serz.ConvertArrayToBytes(send_data))
End Sub

Sub udp_SendPacket (xmit_data() As Byte)
    Dim Packet As UDPPacket
    Packet.Initialize(xmit_data, udp_Ip, udp_Port)
    udpSocketX.Send(Packet)
    Log("Packet Sent")
End Sub

Sub udp_PacketArrived (Packet As UDPPacket)
    Log("Packet Arrived")
    Log($"IN PL= ${Packet.Length} Port= ${Packet.Port} IP= ${Packet.HostAddress}"$)
    If Packet.Length =  0 Then
        Log("Packet Length 0 ")
    End If
    If Packet.Length > 50 Then
        Log("Packet Length > 50 ")
    End If
    Dim msg As Object = bc.HexFromBytes(Packet.Data)
    Log($"${msg}"$)
End Sub
'    Log($"${msg}"$)  which logs the info below ....
'    Waiting For debugger To connect...
'    Program started.
'    Packet Sent
'    Packet Arrived
'    IN PL= 21 Port= 55777 IP= 222.111.7.1
    '7E05083C00019E01A608737472696E6700083E007F...'{000.. to 1024(which is my Buffer Size)}
         ' 3C is "<"                     3E is ">"


Updated the Title so I can find it next year! LOL
 
Last edited:

KiloBravo

Active Member
Licensed User
I ended up hacking a solution together with TCP based on Erel's B4J Network example from the 5th post in this thread.
It seems to work for what I need. 🤷‍♂️ 🙃
 
Upvote 0

OliverA

Expert
Licensed User
Longtime User
From B4J to B4R you do (correctly)
B4J serialize object , send object -> B4R receive object, de-serialize object

But from B4R to B4J you do
B4R serialize object, send object -> B4J receive object
You skipped the de-serialization in the B4J code
 
Upvote 0

KiloBravo

Active Member
Licensed User
So how do I do that ? The syntax from B4R does not work the same on B4J ?
If I use B4Rserializator in the received UDP Packet like ...

B4X:
Sub udp_PacketArrived (Packet As UDPPacket)
    Dim Buffer() As Object = serz.ConvertBytesToArray(Packet.Data)
    For Each o As Object In Buffer
        Log(o)
    Next
End Sub
I get "'Invalid input!"
 
Upvote 0

KiloBravo

Active Member
Licensed User
If I do something like ...
B4X:
Sub udp_PacketArrived (Buffer() As Byte)
    Dim Data() As Object = serz.ConvertBytesToArray(Buffer)
    For Each o As Object In Data
        Log(o)
    Next
End Sub

b4j.example.main:_udp_packetarrived, [Length=37, Offset=0, Host=222.111.7.1, Port=55777]
Error occurred on line: 71
java.lang.IllegalArgumentException: argument Type mismatch
 
Upvote 0

KiloBravo

Active Member
Licensed User
Which I kind of get because I want the bytes (which I assume are B4R/X objects) in the UDP Packet (Packet.Data).
I just can't figure out the syntax/process to convert it back on the B4J side because it is a UDP Packet.
Unless the only way is to get all the bytes in the Packet.Data and use RAF to extract each Object ???
But I could not figure it out.
 
Upvote 0

MicroDrie

Well-Known Member
Licensed User
You can log the value of an object variable 'o' as a litrial string with variable:
B4X:
Log($"${o}"$)
Or you can use the byteconverter library:
B4X:
dim strResult = Dim bc As ByteConverter.StringFromBytes(o, "UTF8")
 
Upvote 0

KiloBravo

Active Member
Licensed User
Yes, MicroDrie.
This just gives me the whole packet as a string or object.
B4X:
    Dim s As String = BytesToString(Packet.Data, Packet.Offset+2, Packet.Length, "utf8")
Log($"${s}"$)

I would then have to split the string using "indexeof" based on the deliminator I used "$".
I was hoping there was something simplier, but I guess not since it is a UDP Packet.
I was going to use async streams but that doesn't seem possible with UDP packets. (At least I don't know how.)
Thanks!

I did get my app working with TCP. Which seems fine especially using "Wait For" in the send and receive comms piece.
 
Upvote 0

KiloBravo

Active Member
Licensed User
From B4J to B4R you do (correctly)
B4J serialize object , send object -> B4R receive object, de-serialize object

But from B4R to B4J you do
B4R serialize object, send object -> B4J receive object
You skipped the de-serialization in the B4J code


Apparently this is how you de-serialize it .....

B4X:
Sub udp_PacketArrived (Packet As UDPPacket)
    Log("Packet Arrived")
    Dim data() As Byte = Packet.Data
    If Packet.Data.Length > Packet.Length Then
    Dim data(Packet.Length) As Byte
    bc.ArrayCopy(Packet.Data, 0, data, 0, Packet.Length)
    End If
    Dim rcvd_data() As Object = serz.ConvertBytesToArray(data)  '''     Private serz As B4RSerializator
    For Each o As Object In rcvd_data
        Log($"${o}"$)
    Next
End Sub

Took me 2 minutes to figure it out once I found the thread below. But I did spend 8 hours of reading threads. LOL !!!


It's the Journey not the Destination ! :cool:
 
Upvote 0
Top