2020-02-16 04:34:00 +08:00
<?xml version="1.0" encoding="UTF-8" ?>
2023-07-06 16:08:05 +08:00
<class name= "UDPServer" inherits= "RefCounted" xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation= "../class.xsd" >
2020-02-16 04:34:00 +08:00
<brief_description >
Helper class to implement a UDP server.
</brief_description>
<description >
A simple server that opens a UDP socket and returns connected [PacketPeerUDP] upon receiving new packets. See also [method PacketPeerUDP.connect_to_host].
2020-07-13 21:45:08 +08:00
After starting the server ([method listen]), you will need to [method poll] it at regular intervals (e.g. inside [method Node._process]) for it to process new packets, delivering them to the appropriate [PacketPeerUDP], and taking new connections.
2020-02-16 04:34:00 +08:00
Below a small example of how it can be used:
2020-11-28 07:33:15 +08:00
[codeblocks]
[gdscript]
2023-02-01 01:21:09 +08:00
# server_node.gd
class_name ServerNode
2020-02-16 04:34:00 +08:00
extends Node
var server := UDPServer.new()
var peers = []
func _ready():
server.listen(4242)
func _process(delta):
2020-07-13 21:45:08 +08:00
server.poll() # Important!
2020-02-16 04:34:00 +08:00
if server.is_connection_available():
2023-03-03 22:42:32 +08:00
var peer: PacketPeerUDP = server.take_connection()
2020-11-28 07:33:15 +08:00
var packet = peer.get_packet()
2020-02-16 04:34:00 +08:00
print("Accepted peer: %s:%s" % [peer.get_packet_ip(), peer.get_packet_port()])
2020-11-28 07:33:15 +08:00
print("Received data: %s" % [packet.get_string_from_utf8()])
2020-02-16 04:34:00 +08:00
# Reply so it knows we received the message.
2020-11-28 07:33:15 +08:00
peer.put_packet(packet)
2020-02-16 04:34:00 +08:00
# Keep a reference so we can keep contacting the remote peer.
peers.append(peer)
for i in range(0, peers.size()):
pass # Do something with the connected peers.
2020-11-28 07:33:15 +08:00
[/gdscript]
[csharp]
2023-02-01 01:21:09 +08:00
// ServerNode.cs
2020-11-28 07:33:15 +08:00
using Godot;
using System.Collections.Generic;
2020-02-16 04:34:00 +08:00
2023-02-01 01:21:09 +08:00
public partial class ServerNode : Node
2020-11-28 07:33:15 +08:00
{
2023-02-01 01:21:09 +08:00
private UdpServer _server = new UdpServer();
private List< PacketPeerUdp> _peers = new List< PacketPeerUdp> ();
2020-11-28 07:33:15 +08:00
public override void _Ready()
{
2023-02-01 01:21:09 +08:00
_server.Listen(4242);
2020-11-28 07:33:15 +08:00
}
2023-02-01 01:21:09 +08:00
public override void _Process(double delta)
2020-11-28 07:33:15 +08:00
{
2023-02-01 01:21:09 +08:00
_server.Poll(); // Important!
if (_server.IsConnectionAvailable())
2020-11-28 07:33:15 +08:00
{
2023-02-01 01:21:09 +08:00
PacketPeerUdp peer = _server.TakeConnection();
2020-11-28 07:33:15 +08:00
byte[] packet = peer.GetPacket();
2023-02-01 01:21:09 +08:00
GD.Print($"Accepted Peer: {peer.GetPacketIP()}:{peer.GetPacketPort()}");
GD.Print($"Received Data: {packet.GetStringFromUtf8()}");
2020-11-28 07:33:15 +08:00
// Reply so it knows we received the message.
peer.PutPacket(packet);
// Keep a reference so we can keep contacting the remote peer.
2023-02-01 01:21:09 +08:00
_peers.Add(peer);
2020-11-28 07:33:15 +08:00
}
2023-02-01 01:21:09 +08:00
foreach (var peer in _peers)
2020-11-28 07:33:15 +08:00
{
// Do something with the peers.
}
}
}
[/csharp]
[/codeblocks]
[codeblocks]
[gdscript]
2023-02-01 01:21:09 +08:00
# client_node.gd
class_name ClientNode
2020-02-16 04:34:00 +08:00
extends Node
var udp := PacketPeerUDP.new()
var connected = false
func _ready():
udp.connect_to_host("127.0.0.1", 4242)
func _process(delta):
if !connected:
# Try to contact server
2023-03-14 05:58:27 +08:00
udp.put_packet("The answer is... 42!".to_utf8_buffer())
2020-02-19 16:55:47 +08:00
if udp.get_available_packet_count() > 0:
2020-02-16 04:34:00 +08:00
print("Connected: %s" % udp.get_packet().get_string_from_utf8())
connected = true
2020-11-28 07:33:15 +08:00
[/gdscript]
[csharp]
2023-02-01 01:21:09 +08:00
// ClientNode.cs
2020-11-28 07:33:15 +08:00
using Godot;
2023-02-01 01:21:09 +08:00
public partial class ClientNode : Node
2020-11-28 07:33:15 +08:00
{
2023-02-01 01:21:09 +08:00
private PacketPeerUdp _udp = new PacketPeerUdp();
private bool _connected = false;
2020-11-28 07:33:15 +08:00
public override void _Ready()
{
2023-02-01 01:21:09 +08:00
_udp.ConnectToHost("127.0.0.1", 4242);
2020-11-28 07:33:15 +08:00
}
2023-02-01 01:21:09 +08:00
public override void _Process(double delta)
2020-11-28 07:33:15 +08:00
{
2023-02-01 01:21:09 +08:00
if (!_connected)
2020-11-28 07:33:15 +08:00
{
// Try to contact server
2023-03-14 05:58:27 +08:00
_udp.PutPacket("The Answer Is..42!".ToUtf8Buffer());
2020-11-28 07:33:15 +08:00
}
2023-02-01 01:21:09 +08:00
if (_udp.GetAvailablePacketCount() > 0)
2020-11-28 07:33:15 +08:00
{
2023-02-01 01:21:09 +08:00
GD.Print($"Connected: {_udp.GetPacket().GetStringFromUtf8()}");
_connected = true;
2020-11-28 07:33:15 +08:00
}
}
}
[/csharp]
[/codeblocks]
2020-02-16 04:34:00 +08:00
</description>
<tutorials >
</tutorials>
<methods >
2021-03-21 18:15:30 +08:00
<method name= "get_local_port" qualifiers= "const" >
2021-07-30 21:28:05 +08:00
<return type= "int" />
2021-03-21 18:15:30 +08:00
<description >
Returns the local port this server is listening to.
</description>
</method>
2020-02-16 04:34:00 +08:00
<method name= "is_connection_available" qualifiers= "const" >
2021-07-30 21:28:05 +08:00
<return type= "bool" />
2020-02-16 04:34:00 +08:00
<description >
2020-07-13 21:45:08 +08:00
Returns [code]true[/code] if a packet with a new address/port combination was received on the socket.
2020-02-16 04:34:00 +08:00
</description>
</method>
<method name= "is_listening" qualifiers= "const" >
2021-07-30 21:28:05 +08:00
<return type= "bool" />
2020-02-16 04:34:00 +08:00
<description >
Returns [code]true[/code] if the socket is open and listening on a port.
</description>
</method>
<method name= "listen" >
2021-07-30 21:28:05 +08:00
<return type= "int" enum= "Error" />
2022-08-07 02:11:48 +08:00
<param index= "0" name= "port" type= "int" />
<param index= "1" name= "bind_address" type= "String" default= ""*"" />
2020-02-16 04:34:00 +08:00
<description >
2022-08-09 07:41:07 +08:00
Starts the server by opening a UDP socket listening on the given [param port]. You can optionally specify a [param bind_address] to only listen for packets sent to that address. See also [method PacketPeerUDP.bind].
2020-02-16 04:34:00 +08:00
</description>
</method>
2020-07-13 21:45:08 +08:00
<method name= "poll" >
2021-07-30 21:28:05 +08:00
<return type= "int" enum= "Error" />
2020-07-13 21:45:08 +08:00
<description >
Call this method at regular intervals (e.g. inside [method Node._process]) to process new packets. And packet from known address/port pair will be delivered to the appropriate [PacketPeerUDP], any packet received from an unknown address/port pair will be added as a pending connection (see [method is_connection_available], [method take_connection]). The maximum number of pending connection is defined via [member max_pending_connections].
</description>
</method>
2020-02-16 04:34:00 +08:00
<method name= "stop" >
2021-07-30 21:28:05 +08:00
<return type= "void" />
2020-02-16 04:34:00 +08:00
<description >
2020-07-13 21:45:08 +08:00
Stops the server, closing the UDP socket if open. Will close all connected [PacketPeerUDP] accepted via [method take_connection] (remote peers will not be notified).
2020-02-16 04:34:00 +08:00
</description>
</method>
<method name= "take_connection" >
2021-07-30 21:28:05 +08:00
<return type= "PacketPeerUDP" />
2020-02-16 04:34:00 +08:00
<description >
2020-07-13 21:45:08 +08:00
Returns the first pending connection (connected to the appropriate address/port). Will return [code]null[/code] if no new connection is available. See also [method is_connection_available], [method PacketPeerUDP.connect_to_host].
2020-02-16 04:34:00 +08:00
</description>
</method>
</methods>
2020-07-13 21:45:08 +08:00
<members >
<member name= "max_pending_connections" type= "int" setter= "set_max_pending_connections" getter= "get_max_pending_connections" default= "16" >
Define the maximum number of pending connections, during [method poll], any new pending connection exceeding that value will be automatically dropped. Setting this value to [code]0[/code] effectively prevents any new pending connection to be accepted (e.g. when all your players have connected).
</member>
</members>
2020-02-16 04:34:00 +08:00
</class>