Although it's possible to read from a Gio.Socket
by wrapping it's file-descriptor in Gio.DataInputStream
, using Gio.Socket.receive_from()
in GJS to receive is not possible because as commented here:
GJS will clone array arguments before passing them to the C-code which will make the call to Socket.receive_from work and return the number of bytes received as well as the source of the packet. The buffer content will be unchanged as buffer actually read into is a freed clone.
Thus, input arguments are cloned and data will be written to the cloned buffer, not the instance of buffer
actually passed in.
Although reading from a data stream is not a problem, Gio.Socket.receive_from()
is the only way I can find to get the remote address from a UDP listener, since Gio.Socket.remote_address
will be undefined. Unfortunately as the docs say for Gio.Socket.receive()
:
For
G_SOCKET_TYPE_DATAGRAM
[...] If the received message is too large to fit inbuffer
, then the data beyondsize
bytes will be discarded, without any explicit indication that this has occurred.
So if I try something like Gio.Socket.receive_from(new Uint8Array(0), null);
just to get the address, the packet is swallowed, but if I read via the file-descriptor I can't tell where the message came from. Is there another non-destructive way to get the incoming address for a packet?
Since you’re using a datagram socket, it should be possible to use
Gio.Socket.receive_message()
and pass theGio.SocketMsgFlags.PEEK
flag to it. This isn’t possible for a stream-based socket, but you are not going to want the sender address for each read you do in that case.If you want improved performance, you may be able to use
Gio.Socket.receive_messages()
, although I am not sure whether that’s completely introspectable at the moment.