Godot: Low level TCP needs refactoring

Created on 14 Mar 2020  Â·  13Comments  Â·  Source: godotengine/godot

Godot version:
3.2.1

OS/device including version:
Windows/Android

Issue description:
I can't explain my frustration with TCP in godot. Just before I start, I have a lot of networking knowledge, worked on several online games so yes I am qualified to answer this. TCP in godot is very unstable, produces different results on different platforms. I am trying to do networking between Windows and Android and there is just no way of moving forward for me. I quote Godot docs "Error connect_to_host ( String host, int port )
Connects to the specified host:port pair. A hostname will be resolved if valid. Returns @GlobalScope.OK on success or @GlobalScope.FAILED on failure." Okay, so why am i getting OK on even failed attempts and even when the host is not even running or does not even exist. So I was like ok maybe its just this way. So I tried the get_status() ==. What happens? On the host side I see that the client connects but on the client side the get_status() DOES NOT RETURN 2 EVEN IF IT HAS CONNECTED!

There are legit always 2 possible results after attempting to connect in NORMAL TCP (other languages) on a blocking connect attempt. Those 2 are either it returns success or failure. NOTHING ELSE. WHY IS THERE A CONNECTING STATE? What does a client.get_status() == 1 (CONNECTING ) even mean? WHYY. Sometimes it will connect but on the client side still return get_status != 2 which is just not making sense?
socket.connect_to_host("192.168.0.198", 8315)
if socket.get_status() == 2:
the if does not get executed even if it connects on the host screen... there is not way on the client side to know if you have connected or not...


if socket.connect_to_host("192.168.0.198", 8315) == OK:

And this will always execute... yeah always no matter if the port is open or if the ip even exists"

So i was like yeah maybe godot has this special tcp state "connecting" so i though logically for a minute and had a plan: as socket.connect_to_host(ip,port) always returns OK. I checked what get_status() returned after trying to connect to a valid host. IT DOES return the state 1 called "connecting" so i was like ok lets put it in a while loop and wait for it to turn to 2 "connected" or 0 "disconnected"

socket.connect_to_host("192.168.0.111", 8315)
while socket.get_status() != 2: # 2 is connected, 0 is disconnected and 1 is connecting
continue
# Guess what? game froze but on the host side it connected

Steps to reproduce:
socket = StreamPeerTCP.new()
print(socket.connect_to_host("invalid but correct format ip", 8315))
print(socket.get_status()) # Will always be 1 / "connected"

OR

socket = StreamPeerTCP.new()
print(socket.connect_to_host("valid host thats running", 8315))
print(socket.get_status()) # Which will always be 1 / "connecting"

Extra

while socket.get_status() != 2:
continue # WHICH WILL FREEZE

Note

Please don't take this as if I'm bashing this wonderful project. I love Godot want it to improve. It might come off as if I am disrespectful by my tone but thats just my frustration eating me up.
Personal opinion: I believe that the entire Connection and Disconnection code needs to be rewritten. The bugs I just mentioned are only a few of what I am facing. For example why does socket.is_connected_to_host() always return true? even if there is no host you are connected to. If you still believe there is nothing wrong. Just try to write client connection code that successfully detects that you have successfully connected to the host. ill be waiting. And also then try that exact code on a client on Windows and host on Android.

bug discussion needs testing windows network porting

Most helpful comment

This is going a bit off topic, but if you feel like you encountered bugs
and fixed them, feel free to open a pull request, so if the fix is valid it
will be included, everyone will benefit from it, and you won't have to
maintain your own version of Godot.

On Sat, Mar 14, 2020, 11:42 Danil notifications@github.com wrote:

Please don't take this as if I'm bashing this wonderful project.

I can confirm that Godot3 does have lots of very frustrated features/bugs
that I did report here alot
and this bugs/features ruin whole godot experience very much

my way to solve this-is creating my own custom Godot build that I have
already, where many thinks are fixed (like bad physics, multithreading, low
performance of GDScript...etc)
I have touch Godot nework and saw that "something work not as expected"
but I did not dig into it, I do not need it right now.

Godot opensource project, and very easy to modify it, that I like the
most, and it most useful feature in Godot for me.

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/godotengine/godot/issues/37036#issuecomment-599039073,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AAM4C3Q3HLVIPW5OMYBDWILRHNNP3ANCNFSM4LH3QTSA
.

All 13 comments

Alright there is one way of knowing if you as the client have connected or not, that is:
socket.connect_to_host("valid ip", 8315)
enter a loop and wait for socket.get_status to turn 2, only 2. It will not become 0 EVEN if it detects a failed attempt I guess. This solution is not a solution but more like You will either connect or restart the game as it will freeze and never turn to 0. ALL OF THIS WOULD BE FIXED IF socket.connect_to_host() was indeed blocking and returned only OK or FAILED as the docs say... Thank you. BTW all of this is to be tested on two separate devices as yes the localhost works somehow, i presume its because the packets never leave the device and somehow socket.get_status does what its supposed to.

easier way to test:
socket = StreamPeerTCP.new()
test on a valid host ip who has hosted a lobby and then on an ip thats not even mapped to something
print(socket.connect_to_host("IP", 8315))
print(socket.is_connected_to_host())
print(socket.get_status())

Steps to reproduce:
socket = StreamPeerTCP.new()
print(socket.connect_to_host("invalid but correct format ip", 8315))
print(socket.get_status()) # Will always be 1 / "connected"

Tried right now:

extends Control

func _ready():
    var socket = StreamPeerTCP.new()
    print(socket.connect_to_host("invalid but correct format ip", 8315))
    print(socket.get_status()) # Will always be 1 / "connected"

I get:

ERROR: getaddrinfo failed! Cannot resolve hostname.
   at: _resolve_hostname (drivers/unix/ip_unix.cpp:112)
26
0

socket = StreamPeerTCP.new()
print(socket.connect_to_host("valid host thats running", 8315))
print(socket.get_status()) # Which will always be 1 / "connecting"

That is expected, TCP takes some time to connect. If you call get_status after some seconds you will get status 2, connected

socket.connect_to_host() was indeed blocking and returned only OK or FAILED as the docs say...

It should not be blocking, it would be detrimental to make it blocking, just check it's status in process.

connect_to_host will return an error if it can't connect, but, given you say you have experience with networking, you should now that there are cases where you don't now if you can connect or not until you timeout (any host behind a firewall that does not send ICMP back to you), which could be a long time, and you don't want to stall your game for 30 seconds.

Btw, this also seems to work

var socket
func _ready():
    socket = StreamPeerTCP.new()
    print(socket.connect_to_host("google.com", 80))
    while socket.get_status() != StreamPeerTCP.STATUS_CONNECTED:
        continue

though I might suggest this as a better solution (to avoid stalling the game while waiting for connection):

var socket
func _ready():
    socket = StreamPeerTCP.new()
    print(socket.connect_to_host("google.com", 80))

func _process(delta):
    if socket.get_status() == StreamPeerTCP.STATUS_CONNECTED:
        print("connected")

Btw, this also seems to work

var socket
func _ready():
  socket = StreamPeerTCP.new()
  print(socket.connect_to_host("google.com", 80))
  while socket.get_status() != StreamPeerTCP.STATUS_CONNECTED:
      continue

This seems not to work on windows but works on other platforms (the _process technique always works instead.)

WHY IS THERE A CONNECTING STATE? What does a client.get_status() == 1 (CONNECTING ) even mean? WHYY

Please, stay calm, the connecting state represent a TCP socket that is still performing the handshake, nothing absurd.

@Faless oh okay okay I see, so there's a connecting state to make the game loop not freeze. Makes sense now, though maybe threads would have been better/clearer for that. And then secondly the socket.is_connected_to_host() what's up with that returning True even in the connecting state.

is_connected_to_host has been left like that for compatibility with older
versions, to avoid breaking user scripts.
Will be changed in 4.0, but again, you can use get_status to get the exact
status so there's no big problem there.

You can use threads if you want, but threads are not always better, for
various reasons, including the fact that some platforms does not support
them.

On Sat, Mar 14, 2020, 11:25 hk-32 notifications@github.com wrote:

@Faless https://github.com/Faless oh okay okay I see, so there's a
connecting state to make the game loop not freeze. Makes sense now, though
maybe threads would have been better/clearer for that. And then secondly
the socket.is_connected_to_host() what's up with that returning True even
in the connecting state.

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/godotengine/godot/issues/37036#issuecomment-599037484,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AAM4C3RIXO3PTHEGZLZ3BGTRHNLQXANCNFSM4LH3QTSA
.

Please don't take this as if I'm bashing this wonderful project.

I can confirm that Godot3 does have lots of very frustrated features/bugs that I did report here alot
and this bugs/features ruin whole godot experience very much

my way to solve this-is creating my own custom Godot build that I have already, where many thinks are fixed (like bad physics, multithreading, low performance of GDScript...etc)
I have touch Godot nework and saw that "something work not as expected" but I did not dig into it, I do not need it right now.

Godot opensource project, and very easy to modify it, that I like the most, and it most useful feature in Godot for me.

hk-32 reading this thread, I think you get to point where Godot docs are lack of critical info, only reading and learning godot source code help you fix that, Godot docs are very far from "be useful" in not simple projects

This is going a bit off topic, but if you feel like you encountered bugs
and fixed them, feel free to open a pull request, so if the fix is valid it
will be included, everyone will benefit from it, and you won't have to
maintain your own version of Godot.

On Sat, Mar 14, 2020, 11:42 Danil notifications@github.com wrote:

Please don't take this as if I'm bashing this wonderful project.

I can confirm that Godot3 does have lots of very frustrated features/bugs
that I did report here alot
and this bugs/features ruin whole godot experience very much

my way to solve this-is creating my own custom Godot build that I have
already, where many thinks are fixed (like bad physics, multithreading, low
performance of GDScript...etc)
I have touch Godot nework and saw that "something work not as expected"
but I did not dig into it, I do not need it right now.

Godot opensource project, and very easy to modify it, that I like the
most, and it most useful feature in Godot for me.

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/godotengine/godot/issues/37036#issuecomment-599039073,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AAM4C3Q3HLVIPW5OMYBDWILRHNNP3ANCNFSM4LH3QTSA
.

@Faless What happens when you run the _ready only code on windows?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

bojidar-bg picture bojidar-bg  Â·  3Comments

rgrams picture rgrams  Â·  3Comments

SleepProgger picture SleepProgger  Â·  3Comments

gonzo191 picture gonzo191  Â·  3Comments

nunodonato picture nunodonato  Â·  3Comments