Trouble in setting up my first TCP Server in Godot GDScript

Godot Version

4.2.2

Question

Hi,

I recently started a school project where we need to create a small TCP server that an Android application can connect to in order to play a tank game. The tablet will send commands to the server to control their tank.

For the server, I am using Godot. I had no issues setting up the environment for the tank game, but I am having trouble with the TCP server part. This is my first time using networking in Godot, and I am using TCPServer (as I understand it, ENetMultiplayerPeer uses UDP, not TCP).

Currently, my script successfully creates the server on the correct port and can send messages to the client. But when I connect with my Python client script, I see the “New client connected”, but I can’t see the messages from my clients. I’m not sure what I am doing wrong in my script.

Additionally, I am implementing the TCP part in GDScript because it feels more cohesive since everything in my project is already in GDScript. However, I am wondering if it might be a good idea to implement this part in C# instead. Would using C# for the TCP server offer any significant advantages?

Here is my script for server.gd:

class_name Server

signal command_received(command)

var server := TCPServer.new()
var clients := []
var port = 8000

func _ready():
  start_server()

func start_server():
  var result = server.listen(port)
  if result == OK:
    print("Server is listening on port %d" % port)
  else:
    print("Failed to start server: %s" % result)

func _process(delta):
  if server.is_connection_available():
    var client = server.take_connection()
    if client:
      clients.append(client)
      var peer = PacketPeerStream.new()
      peer.set_stream_peer(client)
      var data = "Hello from server"
      peer.put_packet(data.to_utf8_buffer())
      print("New client connected")

    for client in clients:
      var peer = PacketPeerStream.new()
      peer.set_stream_peer(client)
      if peer.get_available_packet_count() > 0:
      var packet = peer.get_packet().get_string_from_utf8()
      print("Received: %s" % packet)
      analyze_command(packet, client)

func send_data_to_client(client: StreamPeerTCP, data: String):
  var peer = PacketPeerStream.new()
  peer.set_stream_peer(client)
  peer.put_packet(data.to_utf8_buffer())

Thank in advance for the help

unlikely

Whats wrong with UDP? ENet has a TCP like behavior if you use reliable settings if that is all you care about. BTW TCP tends to be a bad fit for fast pace style games.

PacketPeerStream adds a 4 byte header before the payload. The header is for an unsigned 32 bit integer representing the size of the payload.

I assume what you are experiencing is PacketPeerStream expecting and waiting for a certain amount of data.

In your python script, you will have to add that 4 byte size header before your payload.

Notes on the code

You should create one PacketPeerStream instance per connection taken.

var peers: Array[PacketPeerStream] = []
func _process(_delta):
	if server.is_connection_available():
		var client = server.take_connection()
		if client:
			var peer = PacketPeerStream.new()
			peer.stream_peer = client
			peers.append(peer)
			peer.put_packet("Hello from server".to_utf8_buffer())

	for peer in peers:
		if peer.get_available_packet_count() > 0:
			# And so on...
			pass