deal with UDP packets from outside Godot

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Squatnet
:warning: Old Version Published before Godot 3 was released.

here is a simple client that listens on a port for UDP messages and simply prints them to the console.

extends Node
var port = 8000
var udp = PacketPeerUDP.new()


func _process(delta):
	if (not udp.is_listening()):
		return
	
	while(udp.get_available_packet_count() > 0):
		var packet = str(udp.get_var())
		print(packet)


func _ready():
	var err = udp.listen(port)
	if (err != OK):
		print ("listen Failed")
	else:
		print ("listening on port "+str(port))
	set_process(true)

However i encounter an error

Condition ' type>=Variant::VARIANT_MAX ' is true. returned: ERR_INVALID_DATA At: core/io/marshalls.cpp:47

If i try to use the provided example of the UDP chat client the packets get through fine and are printed to the console as expected

Is there any way to accept messages from outside Godot

:bust_in_silhouette: Reply From: Zylann

get_var will attempt to extract a serialized Variant from the packet. A Variant is used for all variables in GDScript, like a dynamic value that can be of many types. You can see it as a kind of tuple made of a type and a value. When you write var, it’s always going to contain a Variant, which in turn contains whatever Godot supports (int, float, string, Object…).

If your UDP packet doesn’t come from Godot, you can’t use get_var reliably unless you send messages in the exact same format.
In your case, Godot read the type from the data block, but because it’s not the expected format, it gets a “random” number that doesn’t match a Godot type: type>=Variant::VARIANT_MAX error.

You can get data from packets using typed getters instead. However they aren’t accessible directly, you have to use get_packet(), which returns a RawArray.
From the RawArray you can then read… strings. Ew.
http://docs.godotengine.org/en/stable/classes/class_rawarray.html#class-rawarray

I believe you can read more than that, like files, but I don’t remember how^^"

Perfect, Thank you.

Squatnet | 2017-05-03 13:51

I’ve encountered now another problem. The message i’m sending across looks like this "/address","value"
yet when i do packet.get_string_from_ascii() it simply returns /address

how can i get the rest of the packet?

Squatnet | 2017-05-03 15:20

I have no idea… it returns only /adress because it’s zero-terminated, probably.
I’m confused because the StreamPeer base class has all functions you need: StreamPeer — Godot Engine (stable) documentation in English
However you are dealing with PacketPeerUDP here… I think there is a way but it will need to make those classes interact… oh shit, StreamPeer can’t be instantiated. Why is it so difficult to read or write a simple data stream here? xD

You could open an issue on Github explaining your problem and ask for the feature you need: Issues · godotengine/godot · GitHub

Zylann | 2017-05-03 22:44