Files
godot-docs-l10n/classes/zh_Hant/class_upnp.rst

594 lines
28 KiB
ReStructuredText
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

:github_url: hide
.. _class_UPNP:
UPNP
====
**繼承:** :ref:`RefCounted<class_RefCounted>` **<** :ref:`Object<class_Object>`
通用隨插即用UPnP功能用於網路裝置的發現、查詢及埠對應。
.. rst-class:: classref-introduction-group
說明
----
This class can be used to discover compatible :ref:`UPNPDevice<class_UPNPDevice>`\ s on the local network and execute commands on them, like managing port mappings (for port forwarding/NAT traversal) and querying the local and remote network IP address. Note that methods on this class are synchronous and block the calling thread.
To forward a specific port (here ``7777``, note both :ref:`discover()<class_UPNP_method_discover>` and :ref:`add_port_mapping()<class_UPNP_method_add_port_mapping>` can return errors that should be checked):
::
var upnp = UPNP.new()
upnp.discover()
upnp.add_port_mapping(7777)
To close a specific port (e.g. after you have finished using it):
::
upnp.delete_port_mapping(port)
\ **Note:** UPnP discovery blocks the current thread. To perform discovery without blocking the main thread, use :ref:`Thread<class_Thread>`\ s like this:
::
# Emitted when UPnP port mapping setup is completed (regardless of success or failure).
signal upnp_completed(error)
# Replace this with your own server port number between 1024 and 65535.
const SERVER_PORT = 3928
var thread = null
func _upnp_setup(server_port):
# UPNP queries take some time.
var upnp = UPNP.new()
var err = upnp.discover()
if err != OK:
push_error(str(err))
upnp_completed.emit(err)
return
if upnp.get_gateway() and upnp.get_gateway().is_valid_gateway():
upnp.add_port_mapping(server_port, server_port, ProjectSettings.get_setting("application/config/name"), "UDP")
upnp.add_port_mapping(server_port, server_port, ProjectSettings.get_setting("application/config/name"), "TCP")
upnp_completed.emit(OK)
func _ready():
thread = Thread.new()
thread.start(_upnp_setup.bind(SERVER_PORT))
func _exit_tree():
# Wait for thread finish here to handle game exit while the thread is running.
thread.wait_to_finish()
\ **Terminology:** In the context of UPnP networking, "gateway" (or "internet gateway device", short IGD) refers to network devices that allow computers in the local network to access the internet ("wide area network", WAN). These gateways are often also called "routers".
\ **Pitfalls:**\
- As explained above, these calls are blocking and shouldn't be run on the main thread, especially as they can block for multiple seconds at a time. Use threading!
- Networking is physical and messy. Packets get lost in transit or get filtered, addresses, free ports and assigned mappings change, and devices may leave or join the network at any time. Be mindful of this, be diligent when checking and handling errors, and handle these gracefully if you can: add clear error UI, timeouts and re-try handling.
- Port mappings may change (and be removed) at any time, and the remote/external IP address of the gateway can change likewise. You should consider re-querying the external IP and try to update/refresh the port mapping periodically (for example, every 5 minutes and on networking failures).
- Not all devices support UPnP, and some users disable UPnP support. You need to handle this (e.g. documenting and requiring the user to manually forward ports, or adding alternative methods of NAT traversal, like a relay/mirror server, or NAT hole punching, STUN/TURN, etc.).
- Consider what happens on mapping conflicts. Maybe multiple users on the same network would like to play your game at the same time, or maybe another application uses the same port. Make the port configurable, and optimally choose a port automatically (re-trying with a different port on failure).
\ **Further reading:** If you want to know more about UPnP (and the Internet Gateway Device (IGD) and Port Control Protocol (PCP) specifically), `Wikipedia <https://en.wikipedia.org/wiki/Universal_Plug_and_Play>`__ is a good first stop, the specification can be found at the `Open Connectivity Foundation <https://openconnectivity.org/developer/specifications/upnp-resources/upnp/>`__ and Godot's implementation is based on the `MiniUPnP client <https://github.com/miniupnp/miniupnp>`__.
.. rst-class:: classref-reftable-group
屬性
----
.. table::
:widths: auto
+-----------------------------+-------------------------------------------------------------------------+-----------+
| :ref:`bool<class_bool>` | :ref:`discover_ipv6<class_UPNP_property_discover_ipv6>` | ``false`` |
+-----------------------------+-------------------------------------------------------------------------+-----------+
| :ref:`int<class_int>` | :ref:`discover_local_port<class_UPNP_property_discover_local_port>` | ``0`` |
+-----------------------------+-------------------------------------------------------------------------+-----------+
| :ref:`String<class_String>` | :ref:`discover_multicast_if<class_UPNP_property_discover_multicast_if>` | ``""`` |
+-----------------------------+-------------------------------------------------------------------------+-----------+
.. rst-class:: classref-reftable-group
方法
----
.. table::
:widths: auto
+-------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| |void| | :ref:`add_device<class_UPNP_method_add_device>`\ (\ device\: :ref:`UPNPDevice<class_UPNPDevice>`\ ) |
+-------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| :ref:`int<class_int>` | :ref:`add_port_mapping<class_UPNP_method_add_port_mapping>`\ (\ port\: :ref:`int<class_int>`, port_internal\: :ref:`int<class_int>` = 0, desc\: :ref:`String<class_String>` = "", proto\: :ref:`String<class_String>` = "UDP", duration\: :ref:`int<class_int>` = 0\ ) |const| |
+-------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| |void| | :ref:`clear_devices<class_UPNP_method_clear_devices>`\ (\ ) |
+-------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| :ref:`int<class_int>` | :ref:`delete_port_mapping<class_UPNP_method_delete_port_mapping>`\ (\ port\: :ref:`int<class_int>`, proto\: :ref:`String<class_String>` = "UDP"\ ) |const| |
+-------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| :ref:`int<class_int>` | :ref:`discover<class_UPNP_method_discover>`\ (\ timeout\: :ref:`int<class_int>` = 2000, ttl\: :ref:`int<class_int>` = 2, device_filter\: :ref:`String<class_String>` = "InternetGatewayDevice"\ ) |
+-------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| :ref:`UPNPDevice<class_UPNPDevice>` | :ref:`get_device<class_UPNP_method_get_device>`\ (\ index\: :ref:`int<class_int>`\ ) |const| |
+-------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| :ref:`int<class_int>` | :ref:`get_device_count<class_UPNP_method_get_device_count>`\ (\ ) |const| |
+-------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| :ref:`UPNPDevice<class_UPNPDevice>` | :ref:`get_gateway<class_UPNP_method_get_gateway>`\ (\ ) |const| |
+-------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| :ref:`String<class_String>` | :ref:`query_external_address<class_UPNP_method_query_external_address>`\ (\ ) |const| |
+-------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| |void| | :ref:`remove_device<class_UPNP_method_remove_device>`\ (\ index\: :ref:`int<class_int>`\ ) |
+-------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| |void| | :ref:`set_device<class_UPNP_method_set_device>`\ (\ index\: :ref:`int<class_int>`, device\: :ref:`UPNPDevice<class_UPNPDevice>`\ ) |
+-------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
.. rst-class:: classref-section-separator
----
.. rst-class:: classref-descriptions-group
列舉
----
.. _enum_UPNP_UPNPResult:
.. rst-class:: classref-enumeration
enum **UPNPResult**: :ref:`🔗<enum_UPNP_UPNPResult>`
.. _class_UPNP_constant_UPNP_RESULT_SUCCESS:
.. rst-class:: classref-enumeration-constant
:ref:`UPNPResult<enum_UPNP_UPNPResult>` **UPNP_RESULT_SUCCESS** = ``0``
UPNP 命令或發現成功。
.. _class_UPNP_constant_UPNP_RESULT_NOT_AUTHORIZED:
.. rst-class:: classref-enumeration-constant
:ref:`UPNPResult<enum_UPNP_UPNPResult>` **UPNP_RESULT_NOT_AUTHORIZED** = ``1``
未授權在 :ref:`UPNPDevice<class_UPNPDevice>` 上使用該命令。當使用者在其路由器上禁用 UPNP 時,可能會被返回。
.. _class_UPNP_constant_UPNP_RESULT_PORT_MAPPING_NOT_FOUND:
.. rst-class:: classref-enumeration-constant
:ref:`UPNPResult<enum_UPNP_UPNPResult>` **UPNP_RESULT_PORT_MAPPING_NOT_FOUND** = ``2``
在給定的 :ref:`UPNPDevice<class_UPNPDevice>` 上沒有找到給定埠、協定組合的埠對應。
.. _class_UPNP_constant_UPNP_RESULT_INCONSISTENT_PARAMETERS:
.. rst-class:: classref-enumeration-constant
:ref:`UPNPResult<enum_UPNP_UPNPResult>` **UPNP_RESULT_INCONSISTENT_PARAMETERS** = ``3``
參數不一致。
.. _class_UPNP_constant_UPNP_RESULT_NO_SUCH_ENTRY_IN_ARRAY:
.. rst-class:: classref-enumeration-constant
:ref:`UPNPResult<enum_UPNP_UPNPResult>` **UPNP_RESULT_NO_SUCH_ENTRY_IN_ARRAY** = ``4``
No such entry in array. May be returned if a given port, protocol combination is not found on a :ref:`UPNPDevice<class_UPNPDevice>`.
.. _class_UPNP_constant_UPNP_RESULT_ACTION_FAILED:
.. rst-class:: classref-enumeration-constant
:ref:`UPNPResult<enum_UPNP_UPNPResult>` **UPNP_RESULT_ACTION_FAILED** = ``5``
操作失敗。
.. _class_UPNP_constant_UPNP_RESULT_SRC_IP_WILDCARD_NOT_PERMITTED:
.. rst-class:: classref-enumeration-constant
:ref:`UPNPResult<enum_UPNP_UPNPResult>` **UPNP_RESULT_SRC_IP_WILDCARD_NOT_PERMITTED** = ``6``
:ref:`UPNPDevice<class_UPNPDevice>` 不允許源 IP 位址的萬用字元值。
.. _class_UPNP_constant_UPNP_RESULT_EXT_PORT_WILDCARD_NOT_PERMITTED:
.. rst-class:: classref-enumeration-constant
:ref:`UPNPResult<enum_UPNP_UPNPResult>` **UPNP_RESULT_EXT_PORT_WILDCARD_NOT_PERMITTED** = ``7``
:ref:`UPNPDevice<class_UPNPDevice>` 不允許外部埠的萬用字元值。
.. _class_UPNP_constant_UPNP_RESULT_INT_PORT_WILDCARD_NOT_PERMITTED:
.. rst-class:: classref-enumeration-constant
:ref:`UPNPResult<enum_UPNP_UPNPResult>` **UPNP_RESULT_INT_PORT_WILDCARD_NOT_PERMITTED** = ``8``
:ref:`UPNPDevice<class_UPNPDevice>` 不允許內部埠的萬用字元值。
.. _class_UPNP_constant_UPNP_RESULT_REMOTE_HOST_MUST_BE_WILDCARD:
.. rst-class:: classref-enumeration-constant
:ref:`UPNPResult<enum_UPNP_UPNPResult>` **UPNP_RESULT_REMOTE_HOST_MUST_BE_WILDCARD** = ``9``
遠端主機值必須是萬用字元。
.. _class_UPNP_constant_UPNP_RESULT_EXT_PORT_MUST_BE_WILDCARD:
.. rst-class:: classref-enumeration-constant
:ref:`UPNPResult<enum_UPNP_UPNPResult>` **UPNP_RESULT_EXT_PORT_MUST_BE_WILDCARD** = ``10``
外部埠值必須是萬用字元。
.. _class_UPNP_constant_UPNP_RESULT_NO_PORT_MAPS_AVAILABLE:
.. rst-class:: classref-enumeration-constant
:ref:`UPNPResult<enum_UPNP_UPNPResult>` **UPNP_RESULT_NO_PORT_MAPS_AVAILABLE** = ``11``
沒有可用的埠對應。如果埠對應功能不可用,也可能被返回。
.. _class_UPNP_constant_UPNP_RESULT_CONFLICT_WITH_OTHER_MECHANISM:
.. rst-class:: classref-enumeration-constant
:ref:`UPNPResult<enum_UPNP_UPNPResult>` **UPNP_RESULT_CONFLICT_WITH_OTHER_MECHANISM** = ``12``
與其他機制衝突。如果一個埠對應與現有的衝突,可能會被返回,而不是\ :ref:`UPNP_RESULT_CONFLICT_WITH_OTHER_MAPPING<class_UPNP_constant_UPNP_RESULT_CONFLICT_WITH_OTHER_MAPPING>`\ 。
.. _class_UPNP_constant_UPNP_RESULT_CONFLICT_WITH_OTHER_MAPPING:
.. rst-class:: classref-enumeration-constant
:ref:`UPNPResult<enum_UPNP_UPNPResult>` **UPNP_RESULT_CONFLICT_WITH_OTHER_MAPPING** = ``13``
與現有的埠對應相衝突。
.. _class_UPNP_constant_UPNP_RESULT_SAME_PORT_VALUES_REQUIRED:
.. rst-class:: classref-enumeration-constant
:ref:`UPNPResult<enum_UPNP_UPNPResult>` **UPNP_RESULT_SAME_PORT_VALUES_REQUIRED** = ``14``
外部和內部埠值必須相同。
.. _class_UPNP_constant_UPNP_RESULT_ONLY_PERMANENT_LEASE_SUPPORTED:
.. rst-class:: classref-enumeration-constant
:ref:`UPNPResult<enum_UPNP_UPNPResult>` **UPNP_RESULT_ONLY_PERMANENT_LEASE_SUPPORTED** = ``15``
只支援永久租用。在新增埠對應時,不要使用 ``duration`` 參數。
.. _class_UPNP_constant_UPNP_RESULT_INVALID_GATEWAY:
.. rst-class:: classref-enumeration-constant
:ref:`UPNPResult<enum_UPNP_UPNPResult>` **UPNP_RESULT_INVALID_GATEWAY** = ``16``
無效閘道。
.. _class_UPNP_constant_UPNP_RESULT_INVALID_PORT:
.. rst-class:: classref-enumeration-constant
:ref:`UPNPResult<enum_UPNP_UPNPResult>` **UPNP_RESULT_INVALID_PORT** = ``17``
無效埠。
.. _class_UPNP_constant_UPNP_RESULT_INVALID_PROTOCOL:
.. rst-class:: classref-enumeration-constant
:ref:`UPNPResult<enum_UPNP_UPNPResult>` **UPNP_RESULT_INVALID_PROTOCOL** = ``18``
無效協議。
.. _class_UPNP_constant_UPNP_RESULT_INVALID_DURATION:
.. rst-class:: classref-enumeration-constant
:ref:`UPNPResult<enum_UPNP_UPNPResult>` **UPNP_RESULT_INVALID_DURATION** = ``19``
無效持續時間。
.. _class_UPNP_constant_UPNP_RESULT_INVALID_ARGS:
.. rst-class:: classref-enumeration-constant
:ref:`UPNPResult<enum_UPNP_UPNPResult>` **UPNP_RESULT_INVALID_ARGS** = ``20``
無效參數。
.. _class_UPNP_constant_UPNP_RESULT_INVALID_RESPONSE:
.. rst-class:: classref-enumeration-constant
:ref:`UPNPResult<enum_UPNP_UPNPResult>` **UPNP_RESULT_INVALID_RESPONSE** = ``21``
無效回應。
.. _class_UPNP_constant_UPNP_RESULT_INVALID_PARAM:
.. rst-class:: classref-enumeration-constant
:ref:`UPNPResult<enum_UPNP_UPNPResult>` **UPNP_RESULT_INVALID_PARAM** = ``22``
無效參數。
.. _class_UPNP_constant_UPNP_RESULT_HTTP_ERROR:
.. rst-class:: classref-enumeration-constant
:ref:`UPNPResult<enum_UPNP_UPNPResult>` **UPNP_RESULT_HTTP_ERROR** = ``23``
HTTP 錯誤。
.. _class_UPNP_constant_UPNP_RESULT_SOCKET_ERROR:
.. rst-class:: classref-enumeration-constant
:ref:`UPNPResult<enum_UPNP_UPNPResult>` **UPNP_RESULT_SOCKET_ERROR** = ``24``
通訊端錯誤。
.. _class_UPNP_constant_UPNP_RESULT_MEM_ALLOC_ERROR:
.. rst-class:: classref-enumeration-constant
:ref:`UPNPResult<enum_UPNP_UPNPResult>` **UPNP_RESULT_MEM_ALLOC_ERROR** = ``25``
分配記憶體時出錯。
.. _class_UPNP_constant_UPNP_RESULT_NO_GATEWAY:
.. rst-class:: classref-enumeration-constant
:ref:`UPNPResult<enum_UPNP_UPNPResult>` **UPNP_RESULT_NO_GATEWAY** = ``26``
沒有可用的閘道。你可能需要先呼叫 :ref:`discover()<class_UPNP_method_discover>` ,否則發現沒有偵測到任何有效的 IGDInternetGatewayDevices
.. _class_UPNP_constant_UPNP_RESULT_NO_DEVICES:
.. rst-class:: classref-enumeration-constant
:ref:`UPNPResult<enum_UPNP_UPNPResult>` **UPNP_RESULT_NO_DEVICES** = ``27``
沒有可用的裝置。你可能需要先呼叫 :ref:`discover()<class_UPNP_method_discover>`\ ,或者發現沒有偵測到任何有效的 :ref:`UPNPDevice<class_UPNPDevice>`\ 。
.. _class_UPNP_constant_UPNP_RESULT_UNKNOWN_ERROR:
.. rst-class:: classref-enumeration-constant
:ref:`UPNPResult<enum_UPNP_UPNPResult>` **UPNP_RESULT_UNKNOWN_ERROR** = ``28``
未知錯誤。
.. rst-class:: classref-section-separator
----
.. rst-class:: classref-descriptions-group
屬性說明
--------
.. _class_UPNP_property_discover_ipv6:
.. rst-class:: classref-property
:ref:`bool<class_bool>` **discover_ipv6** = ``false`` :ref:`🔗<class_UPNP_property_discover_ipv6>`
.. rst-class:: classref-property-setget
- |void| **set_discover_ipv6**\ (\ value\: :ref:`bool<class_bool>`\ )
- :ref:`bool<class_bool>` **is_discover_ipv6**\ (\ )
如果為 ``true``\ ,則 IPv6 用於 :ref:`UPNPDevice<class_UPNPDevice>` 發現。
.. rst-class:: classref-item-separator
----
.. _class_UPNP_property_discover_local_port:
.. rst-class:: classref-property
:ref:`int<class_int>` **discover_local_port** = ``0`` :ref:`🔗<class_UPNP_property_discover_local_port>`
.. rst-class:: classref-property-setget
- |void| **set_discover_local_port**\ (\ value\: :ref:`int<class_int>`\ )
- :ref:`int<class_int>` **get_discover_local_port**\ (\ )
如果為 ``0``\ ,系統會自動選擇用於發現的本地埠。如果為 ``1``\ ,將從源埠 1900 進行發現(與目的埠相同)。否則,將使用該值作為埠。
.. rst-class:: classref-item-separator
----
.. _class_UPNP_property_discover_multicast_if:
.. rst-class:: classref-property
:ref:`String<class_String>` **discover_multicast_if** = ``""`` :ref:`🔗<class_UPNP_property_discover_multicast_if>`
.. rst-class:: classref-property-setget
- |void| **set_discover_multicast_if**\ (\ value\: :ref:`String<class_String>`\ )
- :ref:`String<class_String>` **get_discover_multicast_if**\ (\ )
用於發現的多播介面。如果為空,則使用預設的多播介面。
.. rst-class:: classref-section-separator
----
.. rst-class:: classref-descriptions-group
方法說明
--------
.. _class_UPNP_method_add_device:
.. rst-class:: classref-method
|void| **add_device**\ (\ device\: :ref:`UPNPDevice<class_UPNPDevice>`\ ) :ref:`🔗<class_UPNP_method_add_device>`
將給定的 :ref:`UPNPDevice<class_UPNPDevice>` 新增到已發現裝置的列表中。
.. rst-class:: classref-item-separator
----
.. _class_UPNP_method_add_port_mapping:
.. rst-class:: classref-method
:ref:`int<class_int>` **add_port_mapping**\ (\ port\: :ref:`int<class_int>`, port_internal\: :ref:`int<class_int>` = 0, desc\: :ref:`String<class_String>` = "", proto\: :ref:`String<class_String>` = "UDP", duration\: :ref:`int<class_int>` = 0\ ) |const| :ref:`🔗<class_UPNP_method_add_port_mapping>`
新增對應,針對給定的協議 ``proto``\ \ ``"TCP"````"UDP"``\ ,預設為 UDP將預設閘道器見 :ref:`get_gateway()<class_UPNP_method_get_gateway>`\ )上的外部埠 ``port``\ (在 1 到 65535 之間,不過推薦使用 1024 以上的埠)對應到本機上的內部埠 ``port_internal``\ 。如果該閘道上已經存在給定的埠與協議的組合,這個方法會嘗試進行覆蓋。如果不希望如此,你可以使用 :ref:`get_gateway()<class_UPNP_method_get_gateway>` 手動獲取閘道,獲取到後呼叫其 :ref:`add_port_mapping()<class_UPNP_method_add_port_mapping>` 方法。請注意,使用 UPnP 轉發公認埠1024 以下)在有些裝置上可能會失敗。
如果埠的對應已存在,有些閘道裝置可能會對其進行更新,有些則會因為衝突而拒絕這個命令,尤其當現有埠對應不是由 UPnP 建立的,或者指向的是別的網路位址(或裝置)的時候。
如果 ``port_internal````0``\ (預設),表示內外部埠相同(使用 ``port`` 的值)。
描述(\ ``desc``\ )會顯示在一些路由器的管理介面上,可以用來識別新增對應的程序。
對應的租賃時長 ``duration`` 可以通過指定秒數來限定。預設的 ``0`` 表示沒有時長,即永久租賃,有些裝置只支援這種永久租賃。請注意,無論是否永久都只是一種請求,閘道仍然可以隨時移除對應(通常發生在重啟閘道後外部 IP 地址發生變化時,也有些型號會在對應不再活動,即若干分鐘無流量時移除)。如果非 ``0``\ (永久),技術規格所允許的範圍是 ``120``\ 2 分鐘)到 ``86400``24 小時)。
可能的返回值見 :ref:`UPNPResult<enum_UPNP_UPNPResult>`\ 。
.. rst-class:: classref-item-separator
----
.. _class_UPNP_method_clear_devices:
.. rst-class:: classref-method
|void| **clear_devices**\ (\ ) :ref:`🔗<class_UPNP_method_clear_devices>`
清除已發現裝置的列表。
.. rst-class:: classref-item-separator
----
.. _class_UPNP_method_delete_port_mapping:
.. rst-class:: classref-method
:ref:`int<class_int>` **delete_port_mapping**\ (\ port\: :ref:`int<class_int>`, proto\: :ref:`String<class_String>` = "UDP"\ ) |const| :ref:`🔗<class_UPNP_method_delete_port_mapping>`
如果預設閘道器上存在對給定埠和協定組合的埠對應,則將其刪除(見 :ref:`get_gateway()<class_UPNP_method_get_gateway>`\ )。\ ``port`` 必須是 1 和 65535 之間的有效埠,\ ``proto`` 可以是 ``"TCP"````"UDP"``\ 。拒絕的原因可能是對應指向其他位址、埠為公認埠1024 以下)、對應不是由 UPnP 新增的。可能的返回值見 :ref:`UPNPResult<enum_UPNP_UPNPResult>`\ 。
.. rst-class:: classref-item-separator
----
.. _class_UPNP_method_discover:
.. rst-class:: classref-method
:ref:`int<class_int>` **discover**\ (\ timeout\: :ref:`int<class_int>` = 2000, ttl\: :ref:`int<class_int>` = 2, device_filter\: :ref:`String<class_String>` = "InternetGatewayDevice"\ ) :ref:`🔗<class_UPNP_method_discover>`
發現本地的 :ref:`UPNPDevice<class_UPNPDevice>`\ 。清除先前發現的裝置的列表。
預設情況下會篩選 IGDInternetGatewayDevice型別的裝置因為這些裝置管理埠轉發。\ ``timeout`` 是等待回應的時間,單位為毫秒。\ ``ttl`` 是生存時間;請在你知道自己在做什麼的時候才碰這個參數。
可能的返回值見 :ref:`UPNPResult<enum_UPNP_UPNPResult>`\ 。
.. rst-class:: classref-item-separator
----
.. _class_UPNP_method_get_device:
.. rst-class:: classref-method
:ref:`UPNPDevice<class_UPNPDevice>` **get_device**\ (\ index\: :ref:`int<class_int>`\ ) |const| :ref:`🔗<class_UPNP_method_get_device>`
返回給定 ``index`` 處的 :ref:`UPNPDevice<class_UPNPDevice>`\ 。
.. rst-class:: classref-item-separator
----
.. _class_UPNP_method_get_device_count:
.. rst-class:: classref-method
:ref:`int<class_int>` **get_device_count**\ (\ ) |const| :ref:`🔗<class_UPNP_method_get_device_count>`
返回已發現的 :ref:`UPNPDevice<class_UPNPDevice>` 的數量。
.. rst-class:: classref-item-separator
----
.. _class_UPNP_method_get_gateway:
.. rst-class:: classref-method
:ref:`UPNPDevice<class_UPNPDevice>` **get_gateway**\ (\ ) |const| :ref:`🔗<class_UPNP_method_get_gateway>`
返回預設閘道器。這是第一個發現的\ :ref:`UPNPDevice<class_UPNPDevice>`\ 也是一個有效的IGDInternetGatewayDevice
.. rst-class:: classref-item-separator
----
.. _class_UPNP_method_query_external_address:
.. rst-class:: classref-method
:ref:`String<class_String>` **query_external_address**\ (\ ) |const| :ref:`🔗<class_UPNP_method_query_external_address>`
返回預設閘道器的外部 :ref:`IP<class_IP>` 位址字串(見 :ref:`get_gateway()<class_UPNP_method_get_gateway>`\ )。錯誤時返回空字符串。
.. rst-class:: classref-item-separator
----
.. _class_UPNP_method_remove_device:
.. rst-class:: classref-method
|void| **remove_device**\ (\ index\: :ref:`int<class_int>`\ ) :ref:`🔗<class_UPNP_method_remove_device>`
``index`` 處的裝置從已發現的裝置列表中移除。
.. rst-class:: classref-item-separator
----
.. _class_UPNP_method_set_device:
.. rst-class:: classref-method
|void| **set_device**\ (\ index\: :ref:`int<class_int>`, device\: :ref:`UPNPDevice<class_UPNPDevice>`\ ) :ref:`🔗<class_UPNP_method_set_device>`
``index`` 處的裝置從已發現的裝置列表中設定為 ``device``\ 。
.. |virtual| replace:: :abbr:`virtual (本方法通常需要使用者覆寫才能生效。)`
.. |required| replace:: :abbr:`required (This method is required to be overridden when extending its base class.)`
.. |const| replace:: :abbr:`const (本方法沒有副作用。不會修改該實例的任何成員變數。)`
.. |vararg| replace:: :abbr:`vararg (本方法除了這裡描述的參數外,還可以接受任意數量的參數。)`
.. |constructor| replace:: :abbr:`constructor (本方法用於建構一個型別。)`
.. |static| replace:: :abbr:`static (本方法無需實例即可呼叫,因此可以直接使用類別名稱呼叫。)`
.. |operator| replace:: :abbr:`operator (本方法描述將本型別作為左運算元時可用的有效運算子。)`
.. |bitfield| replace:: :abbr:`BitField (此值是由下列旗標組成的位元遮罩整數。)`
.. |void| replace:: :abbr:`void (無回傳值。)`