如何从 UDP 侦听器套接字上的传入消息中获取远程地址?

How can I get the remote address from an incoming message on UDP listener socket?

尽管可以通过将文件描述符包装在 Gio.DataInputStream 中来读取 Gio.Socket,但在 GJS 中使用 Gio.Socket.receive_from() 来接收不可能因为 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.

因此,输入参数被克隆,数据将被写入克隆缓冲区,而不是实际传入的buffer实例。

虽然从数据流中读取不是问题,但 Gio.Socket.receive_from() 是我能找到的从 UDP 侦听器获取远程地址的唯一方法,因为 Gio.Socket.remote_address 将是未定义的。不幸的是,正如文档所说 Gio.Socket.receive():

For G_SOCKET_TYPE_DATAGRAM [...] If the received message is too large to fit in buffer, then the data beyond size bytes will be discarded, without any explicit indication that this has occurred.

因此,如果我尝试 Gio.Socket.receive_from(new Uint8Array(0), null); 之类的操作只是为了获取地址,数据包就会被吞下,但如果我通过文件描述符读取,我就无法分辨消息的来源。还有另一种非破坏性的方法来获取数据包的传入地址吗?

由于您使用的是数据报套接字,因此应该可以使用 Gio.Socket.receive_message() 并将 Gio.SocketMsgFlags.PEEK 标志传递给它。这对于基于流的套接字是不可能的,但在这种情况下,您不会希望每次读取都需要发送方地址。

如果你想提高性能,你可以使用 Gio.Socket.receive_messages(),虽然我不确定目前是否完全可以自省。