如何从 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()
,虽然我不确定目前是否完全可以自省。
尽管可以通过将文件描述符包装在 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 inbuffer
, then the data beyondsize
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()
,虽然我不确定目前是否完全可以自省。