Download

TCP Socket Listener, Receiving Binary Data into UE4 From a Python Script!

Rama,

I’m having a Engine Crash issue with the function CreateTCPConnectionListener.



FSocket* ATestActor::CreateTCPConnectionListener(const FString& YourChosenSocketName, const FString& TheIP, const int32 ThePort, const int32 ReceiveBufferSize)
{
	uint8 IP4Nums[4];
	if (!FormatIP4ToNumber(TheIP, IP4Nums))
	{
		return false;
	}

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

	//Create Socket
	FIPv4Endpoint Endpoint(FIPv4Address(IP4Nums[0], IP4Nums[1], IP4Nums[2], IP4Nums[3]), ThePort);
	FSocket* ListenSocket = FTcpSocketBuilder(*YourChosenSocketName).AsReusable().BoundToEndpoint(Endpoint).Listening(8);

	//Set Buffer Size
	int32 NewSize = 0;
	/*---------------> WHERE IT POINTS WHEN CRASHES*/  ListenSocket->SetReceiveBufferSize(ReceiveBufferSize, NewSize);

	//Done!
	return ListenSocket;
}


I’m using a .jar file to send information to the local host(127.0.0.1:7000). I’m using 4.9… Any help on what’s happening would be excellent :(.

EDIT:
Got the output from the crash… looks like it failed to create the socket



[2015.09.15-04.10.42:416][150]LogWorld: Game class is 'derpGameMode'
[2015.09.15-04.10.42:425][150]LogWorld: Bringing World /Game/ThirdPersonCPP/Maps/UEDPIE_0_ThirdPersonExampleMap.ThirdPersonExampleMap up for play (max tick rate 0) at 2015.09.14-23.10.42
[2015.09.15-04.10.42:426][150]LogActor:Warning: GameSession /Game/ThirdPersonCPP/Maps/UEDPIE_0_ThirdPersonExampleMap.ThirdPersonExampleMap:PersistentLevel.GameSession_0 has natively added scene component(s), but none of them were set as the actor's RootComponent - picking one arbitrarily
[2015.09.15-04.10.42:426][150]LogActor:Warning: GameNetworkManager /Game/ThirdPersonCPP/Maps/UEDPIE_0_ThirdPersonExampleMap.ThirdPersonExampleMap:PersistentLevel.GameNetworkManager_0 has natively added scene component(s), but none of them were set as the actor's RootComponent - picking one arbitrarily
[2015.09.15-04.10.42:427][150]LogWorld: Bringing up level for play took: 0.009418
[2015.09.15-04.10.42:429][150]FTcpSocketBuilder: Failed to create the socket RamaSocketListener as configured


Blaah Dx… Any help would be great :(.

that crash is usually a “secondary crash” when it’s already at critical error and trying to shut everything down. :o
Unless you actually are cleaning up the 2d phys environment

UPDATE:

Ok soo I managed to make it not crash.

Now for the logic part:



//Rama's TCP Connection Listener
void ANetworkActor::TCPConnectionListener()
{

    //~~~~~~~~~~~~~
	if (!ListenerSocket)
	{
		return;
	}
    //~~~~~~~~~~~~~
    
    //Remote address
    TSharedRef<FInternetAddr> RemoteAddress = ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->CreateInternetAddr();
    bool Pending;

    // handle incoming connections
    if (ListenerSocket->HasPendingConnection(Pending) && Pending)
    {
		GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, "DERP");    //DOES NOT SHOOT MESSAGE ON SCREEN

		//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
		//Already have a Connection? destroy previous
		if (ConnectionSocket)
		{
			ConnectionSocket->Close();
			ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->DestroySocket(ConnectionSocket);
		}
		//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

		//New Connection receive!
		ConnectionSocket = ListenerSocket->Accept(*RemoteAddress, TEXT("RamaTCP Received Socket Connection"));

		if (ConnectionSocket != NULL)
		{
			//Global cache of current Remote Address
			RemoteAddressForConnection = FIPv4Endpoint(RemoteAddress);

			//UE_LOG "Accepted Connection! WOOOHOOOO!!!";

			//can thread this too
			GetWorldTimerManager().SetTimer(Timer02, this, &ANetworkActor::TCPSocketListener, 0.01, true);
		}
       
    }
}


Now it seems to be that there is no pending connections to the IP Port. I’m trying to figure this out in particular, but it just wont budge :(. I also removed the check for Pending in the if statement



if (ListenerSocket->HasPendingConnection(Pending))


and it outputs my Derp. however, when i get to this:



		if (ConnectionSocket != NULL)
		{
                        GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, "DERP");

			//Global cache of current Remote Address
			RemoteAddressForConnection = FIPv4Endpoint(RemoteAddress);

			//UE_LOG "Accepted Connection! WOOOHOOOO!!!";

			//can thread this too
			GetWorldTimerManager().SetTimer(Timer02, this, &ANetworkActor::TCPSocketListener, 0.01, true);
		}


The derp message wont output as well.

One of two things is happening that I do not know:

1.) Do I need to find a way to open the IP Port? because it seems to me there’s a wall of some sort blocking it’s way to getting it?

2.) Trying to figure out why the ConnectionSocket is NULL after we initialize it?

Any help would be amazing :(.
1-800-123-HELP O_o

UPDATE: One last thing discovered:

So I’m back to the issue with the Engine Crashing and pointing to the ListenSocket

I’ve discovered that in order to make this work, I had to do the following:

1.) Start the engine
2.) Run the command line to open the .jar file to send info to the IP Port
3.) We have communication

HOWEVER

It’s causing the crash at that spot. Is there a buffer size issue maybe? What do I do about this ? :frowning:

*bump Dx. Anything to lead me in the right direction :frowning:

Is there anyone who got this working on 4.9?
Im following the tutorial but I’m not able to import Networking.h in the firsplace.
When I’m using the full location to import the headerfile the compiler errors get too much to count.
Please if someone can help me out…

Thanks in advance.

Hi,

I got it working in 4.9 But i’m running into another problem. It only works for one time after opening the project. I think the problem lies within not closing the socket. Then again I’m not really a programmer so my idea could be way off. Maybe someone could point me in the right direction how to close the socket before exiting.

Hi I’m still fighting with the code… but got most of it working, you have to:
->Close the socket
Then With IsocketSystem destroy it

you can do this on the BeginDestroy event

Good luck

Hi, already got it working. Apparently it’s a known bug that some sockets won’t close. I fixed it with the code in this topic:

https://answers.unrealengine.com/questions/211599/473-tcp-ports-not-closing.html

The only thing i’ve changed is that i don’t use a bool to determine if the connection is open, I always force close it before ending. You can always p.m. me if you need the code, happy to share it.

Hi Rama, hi everyone,

Thanks a lot for the great tutorial. I am working on 4.9 and have tried to follow along with your setup. Most of it was easily portable to 4.9. One minor change I had to do was include a FTimerHandle into the timer functions, since Actors can no longer be cast to FTimerHandle. Now I am stuck with one issue I can’t seem to solve. My build fails when I am trying to create the FInternetAddr shared pointer. Apperantly FInternetAddr is abstract!? The error I am getting is

C:\Program Files\Epic Games\4.9\Engine\Source\Runtime\Core\Public\Templates\SharedPointer.h(162): error C2259: 'FInternetAddr' : cannot instantiate abstract class

I have searched the documentation for any none abstract classes derived from FInternetAddr to solve this issue, but could not find anything. Looking into the docs (here) FInternetAddr’s description (as part of the Sockets module) only states:

Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.

Might this explain the error I am getting?
Any help would be greatly appreciated. Thx :wink:

Have you included “Sockets” & “Networking” to the module names of your Build.cs?

I’m getting a crash at the same point as well but my crash report seems different.
Have you got it to work by now?

here is my crash report:


UE4Editor_MyProject2_358!AMyPlayerController::CreateTCPConnectionListener() [c:\users\hciadmin\documents\unreal projects\myproject2\source\myproject2\myplayercontroller.cpp:93]
UE4Editor_MyProject2_358!AMyPlayerController::StartTCPReceiver() [c:\users\hciadmin\documents\unreal projects\myproject2\source\myproject2\myplayercontroller.cpp:32]
UE4Editor_MyProject2_358!AMyPlayerController::Launch() [c:\users\hciadmin\documents\unreal projects\myproject2\source\myproject2\myplayercontroller.cpp:14]
UE4Editor_Engine!FInputActionUnifiedDelegate::Execute() [d:\buildfarm\buildmachine_++depot+ue4-releases+4.10\engine\source\runtime\engine\classes\components\inputcomponent.h:181]
UE4Editor_Engine!UPlayerInput::ProcessInputStack() [d:\buildfarm\buildmachine_++depot+ue4-releases+4.10\engine\source\runtime\engine\private\userinterface\playerinput.cpp:1117]
UE4Editor_Engine!APlayerController::ProcessPlayerInput() [d:\buildfarm\buildmachine_++depot+ue4-releases+4.10\engine\source\runtime\engine\private\playercontroller.cpp:2281]
UE4Editor_Engine!APlayerController::TickPlayerInput() [d:\buildfarm\buildmachine_++depot+ue4-releases+4.10\engine\source\runtime\engine\private\playercontroller.cpp:3816]
UE4Editor_Engine!APlayerController::PlayerTick() [d:\buildfarm\buildmachine_++depot+ue4-releases+4.10\engine\source\runtime\engine\private\playercontroller.cpp:1950]
UE4Editor_Engine!APlayerController::TickActor() [d:\buildfarm\buildmachine_++depot+ue4-releases+4.10\engine\source\runtime\engine\private\playercontroller.cpp:3892]
UE4Editor_Engine!FActorTickFunction::ExecuteTick() [d:\buildfarm\buildmachine_++depot+ue4-releases+4.10\engine\source\runtime\engine\private\actor.cpp:107]
UE4Editor_Engine!FTickFunctionTask::DoTask() [d:\buildfarm\buildmachine_++depot+ue4-releases+4.10\engine\source\runtime\engine\private	icktaskmanager.cpp:141]
UE4Editor_Engine!TGraphTask<FTickFunctionTask>::ExecuteTask() [d:\buildfarm\buildmachine_++depot+ue4-releases+4.10\engine\source\runtime\core\public\async	askgraphinterfaces.h:779]
UE4Editor_Core!FTaskThread::ProcessTasks() [d:\buildfarm\buildmachine_++depot+ue4-releases+4.10\engine\source\runtime\core\private\async	askgraph.cpp:539]
UE4Editor_Core!FTaskThread::ProcessTasksUntilQuit() [d:\buildfarm\buildmachine_++depot+ue4-releases+4.10\engine\source\runtime\core\private\async	askgraph.cpp:340]
UE4Editor_Core!FTaskGraphImplementation::WaitUntilTasksComplete() [d:\buildfarm\buildmachine_++depot+ue4-releases+4.10\engine\source\runtime\core\private\async	askgraph.cpp:1140]
UE4Editor_Engine!FTaskGraphInterface::WaitUntilTaskCompletes() [d:\buildfarm\buildmachine_++depot+ue4-releases+4.10\engine\source\runtime\core\public\async	askgraphinterfaces.h:212]
UE4Editor_Engine!FTickTaskSequencer::ReleaseTickGroup() [d:\buildfarm\buildmachine_++depot+ue4-releases+4.10\engine\source\runtime\engine\private	icktaskmanager.cpp:285]
UE4Editor_Engine!FTickTaskManager::RunTickGroup() [d:\buildfarm\buildmachine_++depot+ue4-releases+4.10\engine\source\runtime\engine\private	icktaskmanager.cpp:1206]
UE4Editor_Engine!UWorld::RunTickGroup() [d:\buildfarm\buildmachine_++depot+ue4-releases+4.10\engine\source\runtime\engine\private\leveltick.cpp:701]
UE4Editor_Engine!UWorld::Tick() [d:\buildfarm\buildmachine_++depot+ue4-releases+4.10\engine\source\runtime\engine\private\leveltick.cpp:1150]
UE4Editor_UnrealEd!UEditorEngine::Tick() [d:\buildfarm\buildmachine_++depot+ue4-releases+4.10\engine\source\editor\unrealed\private\editorengine.cpp:1347]
UE4Editor_UnrealEd!UUnrealEdEngine::Tick() [d:\buildfarm\buildmachine_++depot+ue4-releases+4.10\engine\source\editor\unrealed\private\unrealedengine.cpp:361]
UE4Editor!FEngineLoop::Tick() [d:\buildfarm\buildmachine_++depot+ue4-releases+4.10\engine\source\runtime\launch\private\launchengineloop.cpp:2427]
UE4Editor!GuardedMain() [d:\buildfarm\buildmachine_++depot+ue4-releases+4.10\engine\source\runtime\launch\private\launch.cpp:142]
UE4Editor!GuardedMainWrapper() [d:\buildfarm\buildmachine_++depot+ue4-releases+4.10\engine\source\runtime\launch\private\windows\launchwindows.cpp:126]
UE4Editor!WinMain() [d:\buildfarm\buildmachine_++depot+ue4-releases+4.10\engine\source\runtime\launch\private\windows\launchwindows.cpp:200]
UE4Editor!__scrt_common_main_seh() [f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl:264]
kernel32
ntdll

Aside from that I’m a little bit confused why there’s no ReceiveBufferSize in the parameters when “CreateTCPConnectionListener” is called in “StartTCPReceiver”. How does this work if there’s no value given to it? Gave it 1024 but didn’t change anything.

Thank you for your attention.

Hi, I have tried to implement code mentioned above, but I had some issues with socket ListenerSocket->HasPendingConnection used. I do not know reason why this function never set my Pending variable to true(I am using unreal engine 4.9.2).

Finally, I managed to get code going with help of FTcpLitener instead of FSocket like so:

Listener = new FTcpListener(FIPv4Endpoint(FIPv4Address(127, 0, 0, 1), 8890));
Listener->OnConnectionAccepted().BindUObject(this, &AMyActor::foo);

bool AMyActor::foo(FSocket* ClientSocket, const FIPv4Endpoint& ClientEndpoint){
ConnectionSocket = ClientSocket;
return true;
}

P.S. @Rama : If you let me do so, I will be more than glad to update wiki page. (Did not wanted to do so without asking ;-))

Dear Gibli,
**[FONT=Comic Sans MS]
Welcome to the UE4 Forums Gibli! **

I am glad to have you here!

You could feel free to post your code as an alternative to the original, adding a section like “4.9 Delegate Code Solution”

That will get it available to everyone, and then when I get a chance I will investigate the situation.

:slight_smile:

Rama

Hey Rama, great tutorial.

When I send data from my C# server to the UE4 client, It always misses the first packet.

For E.G User types in correct login credentials. Presses login button, login button sends the data to the server. Server checks DB, and says yes, you can login. Server sends “True” to Ue4 Client. Ue4 client receives -1 “ReceivedData.Num() );”

So the UE4 client enters the wrong user details, sends to server, sever says no, sends false, and user gets true (From the first packet sent) and logs in, despite the server saying no.

Basically, it’s ping pong, but my UE4 client misses first packet. Please help!

Hey Rama,

Thank you for the tutorial! I’m having issues with the #include “Networking.h” It seems to work if I include “Runtime/Networking/Public/Networking.h”, however, this causes several new errors (IE: cannot open source file “Sockets.h”, cannot open source file “SocketSubsystem.h”, “IPv4SubnetMask.h”, etc). Clearly VS isn’t looking in or doesn’t have access to a directory that I need in order to use these include files. How can I get access to them? I’m using VS 2015.

Solution: It seems closing the project, selecting the .uproject in windows explorer and Generate Visual Studio Project Files solves the issue for some reason. I found the solution here:
https://answers.unrealengine.com/questions/180115/47-461-problems-including-headers-to-dependency-bu.html

However, more errors show up for me.
‘Laaaauuunch’: is not a member of ‘my class name’
‘StartTCPReceiver’: identifier not found

‘VShow’: identifier not found, etc.

Hi Rama,
thanks for putting up so many awesome tutorials.

To make the network code work with the current stable version of UE4 a few little things need to be changed:
**
Within the Header:**

bool StartTCPReceiver(const FString& YourChosenSocketName, const FString& TheIP, const int32 ThePort);
FSocket* CreateTCPConnectionListener(const FString& YourChosenSocketName, const FString& TheIP, const int32 ThePort, const int32 ReceiveBufferSize = 2*1024*1024);
void TCPConnectionListener();
void TCPSocketListener();
bool FormatIP4ToNumber(const FString& TheIP, uint8 (&Out)[4]);
FString StringFromBinaryArray(const TArray&lt;uint8&gt;& BinaryArray);
void LaunchNetwork();

virtual void BeginDestroy(); // without this, the code runs well – once. The second time, the Editor crashes.

//  TCP networking
FSocket* ListenerSocket;
FSocket* ConnectionSocket;
FIPv4Endpoint RemoteAddressForConnection;
FTimerHandle tcpSocketListenerTime_handler; // NEW
FTimerHandle tcpConnectionListenerTime_handler; // NEW

**
Within the cpp file:**

in StartTCPReceiver()

//Start the Listener! //thread this eventually
GetWorldTimerManager().ClearTimer(tcpConnectionListenerTime_handler); // properly initialize
GetWorldTimerManager().SetTimer(tcpConnectionListenerTime_handler, this, &::ATCPTestCharacter::TCPConnectionListener, 0.01, true); // SetTimer now needs an FTimerHandle

Basically the same for TCPConnectionListener()
//can thread this too
GetWorldTimerManager().ClearTimer(tcpSocketListenerTime_handler); // properly initialize
GetWorldTimerManager().SetTimer(tcpSocketListenerTime_handler, this, &ATCPTestCharacter::TCPSocketListener, 0.01, true); // SetTimer now needs an FTimerHandle

void ATCPTestCharacter::BeginDestroy() //clean up to prevent crashing the Editor
{
// Call the base class
Super::BeginDestroy();
UE_LOG(LogTemp, Warning, TEXT(“Closing Sockets”));
if(ListenerSocket!=nullptr) {
ListenerSocket->Close();
ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->DestroySocket(ListenerSocket);
}

if(ConnectionSocket!=nullptr) {
    ConnectionSocket-&gt;Close();
    ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)-&gt;DestroySocket(ConnectionSocket);
}

}

//Blinky0815

Dear Blinky,

Hiii there!

Thank you for sharing your research!

If you’d like, you can wrap your code improvements like this
openbracket CODE closebracket
your code
openbracket/codeclosebracket

replacing openbracket with
and closebracket with ]

Results in this



void samplecode()
{
    Yay!
}


and then others will find your wonderful code improvements easier to read!

:heart:

Rama

Hi guys! I’m new to unreal, still studying. Thanks for Rama’s tutorial. After implement the code. I have some unsolved errors hope to get some help.

my visual studio 2015 keep telling me I have undefined GetWorldTimerManager() & VShow(). Did I miss including something?

And I also receive the error shows that I can’t add void in front of this → void tcpiptest::tcpiptest()

I’m using ue4.13.1 thanks for helping me.

Hi Rama! Thanks for your tutorial. I’m new to python and unreal. I follow your tutorial build the unreal project, and it can start a tcp server, but I don’t know how to send message from python. Could you please share your python script? thank you in advance!