[4.12.5] FSocket::GetConnectionState() returns incorrect value when disconnected

Why doesn’t the value returned by FSocket::GetConnectionState() change to ConnectionError (instead of Connected) when the connections breaks (by disconnecting from the internet, or by stopping the server, or by the server disconnecting the client)?

I think the problem is caused by doing (WriteState == ESocketBSDReturn::Yes || ReadState == ESocketBSDReturn::Yes), since reading will also be possible when there is no connection, right?

.

Besides that, can [Sockets/Private/BSDSockets/SocketsBSD.h] and [Sockets/Private/BSDIPv6Sockets/SocketsBSDIPv6.h] be moved to the public folder, and can the HasState function be made public in both?

With that, people can experiment and fix problems like these themselves.

Hey ,

Thanks for the feedback. I will be looking into the issue of GetConnectionState( ) returning the wrong state when disconnecting from the internet, stopping the server, or the server disconnecting the client.

When it comes to the ability to move .h files to a public folder and make the HasState( ) function public for them, you can get the source code for the engine and make these changes yourself. You can find more about how to do this here:

[][1]

[1]:

Thanks for looking into it.

I really would like to see the headers and HasState function be made public though, because without that, I won’t be able to use them in a code plugin. Not only that, but the code would break every time I would update the engine as well. All in all, it would be a lot better if important headers and functions like these would become public.

I have gone through making a TCP server and using UE4 FSocket to connect into it and check the clients state with FSocket::GetConnectionState( ), including sending data between server and client. Personally, I haven’t come across anything that would seem like GetConnectionState( ) is behaving incorrectly, even with doing things like closing the server, disconnecting, or the server kicking the client.

With that said, there is a future fix UE-27542 for something similar, which can be here:

https://answers.unrealengine.com/questions/336960/fsocket-problems-with-getconnectionstate-and-send.html

If you are still having issues and it is critical to your project, please post with either the project itself or with code samples, so I can get some context to the issue you are having.

I have been working with your project and the plugin and there is definitely some issues with the GetConnectionState( ) return value, depending on what happens with the connection.

It feels like that if the FSocket has a connection and that connection is closed via some method other than itself changing it, such as calling Disconnect( ) or Connect( ), the ConnectionState is not updated. As an example, if the server is to close, the FSocket state is going to stay SCS_Connected, even though the connection to the server is no longer existing.

As mentioned before, this issue is being tracked and there is development support for updating how GetConnectionState works. I will be keeping an eye on its progress.

My best recommendation now is to have the server call all the connected clients, if it can, when it is closing, to have them close the connection from the client end.

Something like (sudo code):

function ServerClosing()
{
	for( int i = 0; i < ConnectedClients.Num(); i++ )
	{
		ConnectedClients[ i ]->TellDisconnect();
	}
	Close();
}

Or, you could have a time period where each client disconnects and then tries to reconnect, which isn’t ideal but should keep a connection to the server as long as the server is valid.

This could also be another way to make sure the connection is valid when using Send( ):

To me it’s pretty obvious what’s going wrong, like I said before, reading from a socket can still be possible after a disconnect, the state should not ever be used to verify if there is a connection or not.

Using the state to verify the connection is exactly what happens in GetConnectionState(), which is why it gives incorrect results.

Hey ,

My apologies. I’ve put too much faith in GetConnectionState( ). You’re completely right in regards to the conditional statements that decide whether or not the CurrentState is SCS_Connected or SCS_NotConnected.

The problem I am seeing is that WriteState and ReadState can either come back as ESocketBSDReturn::Yes or ESocketBSDReturn::No with a valid connection, which is why I think the developer checks for either.

What I have noticed is that generally during the valid connection, WriteState comes back as ESocketBSDReturn::Yes and ReadState comes back ESocketBSDReturn::No. Once I close my server that the FSocket is connected to, ReadState comes back as ESocketBSDReturn::Yes. But, this is only on my end.

I wouldn’t recommend this as it doesn’t feel correct but if you really want to:

[\Runtime\Sockets\Private\BSDSockets\SocketsBSD.cpp]

[

On my end, this will change the state when my server is closed. Sometimes, I even lose the reference to the current FSocket created, which is kind of bad in its own way.

Sorry for not having a definitive answer on this. The development team is aware of it and hopefully there is a fix on the way.

That is not correct either, reading the socket can also be possible if there is data to be , which can and usually will happen during a connection.

GetConnectionState() should only check the write state, since writing should always be possible when there is a connection, and never when there is no connection.

It should simply be this:

if( WriteState == ESocketBSDReturn::Yes )
{
/* connected */
}
else
{
/* not connected or disconnected */
}

Again, I would have really liked to see the headers and HasState() be public, because then I would already have fixed this problem in my plugin.

Sounds like you’re on a better path than I am.

Good luck.

Hey, I’ve checked the 4.13 p1 code, but it still hasn’t been fixed. Is there an estimated date or engine version the fix will be in?

The current note is that UE-27542 is not a priority item for the networking development team to work on and they haven’t given a time frame for when this issue may be addressed.

Wanted to mention that we’ve run into this too. UE-27542 doesn’t seem to show up in issues.unrealengine.com, so consider this an upvote to get it into the mainline. An alternative to the write-only test given, is to test to see how many bytes are to be , if it’s zero then connection is closed. The internet seems split on the “right way to do it”.

Hey ColdlronPoz,

Here is the link to the public tracker:

https://issues.unrealengine.com/issue/UE-27542

It has been more than half a year, why is this issue still not fixed?

I’ve tested pull request https://github.com/EpicGames/UnrealEngine/pull/2882
and it did the job, why isn’t it pulled in yet?

.

Not only that, but it gets even weirder: In the IPv6 socket code, it is done correctly! (meaning, the state is not used to validate the connection)

Compare SocketsBSD::GetConnectionState() with SocketsBSDIPv6::GetConnectionState().

Can the person who made the IPv6 code take a look at the IPv4 code? (it seems “Ryan Gerleve” made the IPv6 code)

Hey -

As per the public tracker link Langley provided, this issue is still open and currently backlogged. If you’re able to incorporate the pull request fix into your engine, then I would advise to continue using that fix locally.

Hi, thanks for the reply.

The public tracker link links to a problem that doesn’t have much to do with this one.

The problem of the public tracker is: data doesn’t send until GetConnectionState is called.

The problem here is: the socket doesn’t disconnect when the connection is broken (either by a failure in the connection, or by the server disconnecting the client).

It seems a bit weird that these two dissimilar problems are grouped together as one in the public issue tracker, since they are both different problems that require a different solution.

I can (and am) using the fix locally, but that doesn’t fix the problem for everyone of course. Every game or application that uses sockets now will bug out when their internet connection breaks, or when the server disconnects the client. Having this problem actually fixed solves important bugs in a lot of games and applications, making them more stable.

UE-27542 has multiple notes attached to the ticket for GetConnectionState() issues. In one of the attached notes, also provides a link back to this specific post for reference. We are still aware of this issue however we do not have a timeframe on when a fix will be available.

This bug is still here in 4.25, several years later.
If the server closes the connection without telling the client, GetConnectionState() returns ESocketConnectionState::SCS_Connected forever even though the connection is long way gone.

The following workaround is working though:

bool bIsConnected = Socket->GetConnectionState() == ESocketConnectionState::SCS_Connected;
#if PLATFORM_HAS_BSD_SOCKETS || PLATFORM_HAS_BSD_IPV6_SOCKETS
{
	bool bHasPendingConnection = false;
	const bool bSuccess = Socket->HasPendingConnection(bHasPendingConnection);
	bIsConnected = bSuccess && !bHasPendingConnection;
}
#endif

I’m not sure how your workaround works, the problem however I do know about. They check if a socket is readable to see if it’s connected or not, which makes no sense, since it will always return true, whether it’s disconnected or not.

I’ve posted a bug report for this several years ago, and even though it’s just 3 lines that the pull request changed, and even though their IPv6 socket code does do it right (as in it ignores the readable state), epic couldn’t be bothered to look into it and to pull the fix into the engine.

The pull request can be found here: https://github.com/EpicGames/UnrealEngine/pull/2882

I closed it after waiting for ~2 years as it was just embarrassing, but the fix is still correct and valid.