Download

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

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<uint8>& 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->Close();
    ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->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!

hello, compile error fatal error C1083: Unable to open include file : “fbxsdk.h”: No such file or directory,how to solve the error?

Hi Rama!

Thanks for sharing your code. I did manage to send data from the python code to Unreal, but the kind of data I’m trying to send is images. I have already received the byte array of the image, and now I’m trying to convert it to texture and show it in a plane inside the game. I’ve searched ways to render texture in real time and mixed the approach I found with your code, I did manage to show something on the plane, but it is not the image, I think somethin is wrong, maybe the color channels are in different order, I don’t know. Have you ever tried to send image from python code and render it on Unreal application?

This is the approached I used to render textures in real time: http://www.showmethatagain.com/2015/11/13/dynamic-textures-in-ue4/

I use the updateTexture method to put the byte array received:

the byte array I receive from the python will be the dtBuffer as a paramether in the methode:

UpdateTextureRegions(dtTexture, 0, 1, dtUpdateTextureRegion, dtBufferSizeSqrt, (uint32)4, dtBuffer, false)
dtMaterialInstanceDynamic->SetTextureParameterValue(“DynamicTextureParam”, dtTexture);

Hello, everybody.
I would like to create and run simple plugin to receive data from android device used as tcp client and receive it inside of unreal engine plugin, I was able to create tcp listener, but since there is very little documentation, and I am new to unreal engine, and also c++, and also to networking communication. Android application is sending data, i was able to check it with socket test. I was also trying to follow rama’s tutorial on tcp listener, however I was still not able to receive any data with my plugin.

here is code sample i used:


UE_LOG(LogTemp, Warning, TEXT("Connector Plugin Module loaded!"));
    
    	FIPv4Address ip;
    	const std::string server_ip = "127.0.0.1";
    	int port = 8888;
    	if (!FIPv4Address::Parse(UTF8_TO_TCHAR(server_ip.c_str()), ip))
    	{
    		UE_LOG(LogTemp, Warning, TEXT(" FIPv4Address::Parse error!"));
    	}
    
    	TSharedRef<FInternetAddr> Addr = ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->CreateInternetAddr();
    	Addr->SetIp( ip.Value );
    	Addr->SetPort( port );
    
    	FSocket* listenerSocket = ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->CreateSocket(NAME_Stream, TEXT("default"));
    	if (!listenerSocket)
    	{
    		UE_LOG(LogTemp, Warning, TEXT("Error create socket!"));
    	}
    	
    
    	//FIPv4Endpoint Endpoint = FIPv4Endpoint(ip, port);
    	FTcpListener myListener = FTcpListener(*listenerSocket, FTimespan(0, 0, 30));
    
    
    	uint32 size;
    
    	while(true)
    	{
    		if(!listenerSocket->HasPendingData(size) ){
    		
    			UE_LOG(LogTemp, Warning, TEXT("No Data waiting!"));
    		}
    
    		uint8 Data[1000];
    		int32 BytesRead;
    		if (!listenerSocket->Recv(Data, sizeof(Data), BytesRead))
    		{
    			UE_LOG(LogTemp, Warning, TEXT("Error recv!"));
    
    		}
    		else    		{
    			UE_LOG(LogTemp, Warning, TEXT("OK recv!"));
    		}
    	}

if you have any working solution, give me some advice advice, i know i am doing something ( or maybe everything) wrong, but i tried so many solutions.

If you want to create a texture from a byte array containing compressed image data, you might want to look into using UE4’s builtin ImageWrapper module, which has all the required logic to detect, decompress and decode a variety of image formats. I don’t want to toot my own horn too much, but it just so happens that I added an article to the wiki a few weeks ago which demonstrates how to do this:

You should take a look at the part that starts with “Detect the image type using the ImageWrapper module” and ends with “Create the texture and upload the uncompressed image data”. Instead of copying the customized CreateTexture function, you could also use the standard UTexture2D::CreateTransient function, if you don’t mind that the texture gets created inside the transient package.

I noticed a couple of things about your code:

  1. You define and parse an IP address, but you don’t use it to configure your TCP socket or listener.
  2. You create an FTcpListener to wrap around the raw socket, but you don’t make use of it anywhere. Rather, you proceed to poll and read from the raw socket.

The whole point of the FTcpListener class is to hide the complexities of dealing with raw sockets and background threads, and allow you to simply deal with incoming connections if and when they come. FTcpListener can take care of creating the socket, so you don’t have to do that yourself, and will create a background thread that polls the socket for incoming connections. All you need to do is register a function that handles incoming connections and then reads & processes the data from a single connection.

Here’s an example that I tested and that worked for me. I put this inside a generic AMyActor example class, so you’ll have to adapt the code to your situation:

Header



#include "Networking.h"
#include "MyActor.generated.h"

UCLASS()
class AMyActor : public AActor
{
	GENERATED_BODY()

public:
	virtual void BeginPlay() override;

	virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;

private:
	bool HandleConnectionAccepted(FSocket* Socket, const FIPv4Endpoint& Endpoint);

	FTcpListener* MyListener;
};


Source



void AMyActor::BeginPlay()
{
	Super::BeginPlay();

	// Accept connections from any remote IP address. Change this to FIPv4Address::InternalLoopback if you only want to accept connections from the same machine.
	FIPv4Address ip = FIPv4Address::Any;
	uint16 port = 8888;

	// Create a TCP listener and configure it with an endpoint. This way, the TcpListener will take care of creating and destroying the underlying socket.
	FIPv4Endpoint Endpoint(ip, port);
	MyListener = new FTcpListener(Endpoint);

	// Bind a function to handle incoming TCP connections and read data from the socket.
	// We're using BindUObject here because this is being called from a UObject-derived class. Use BindRaw when calling this from a non-UObject class.
	MyListener->OnConnectionAccepted().BindUObject(this, &AMyActor::HandleConnectionAccepted);

	UE_LOG(LogTemp, Log, TEXT("TCP server listening at: %s"), *Endpoint.ToString());
}

void AMyActor::EndPlay(const EEndPlayReason::Type EndPlayReason)
{
	// Make sure we stop the TCP listener and its background thread when ending the game.
	if (MyListener != nullptr)
	{
		MyListener->OnConnectionAccepted().Unbind();

		delete MyListener;
		MyListener = nullptr;
	}

	Super::EndPlay(EndPlayReason);
}

bool AMyActor::HandleConnectionAccepted(FSocket* Socket, const FIPv4Endpoint& Endpoint)
{
	uint32 DataSize;
	uint8 Data[1000];
	int32 BytesRead;

	UE_LOG(LogTemp, Log, TEXT("Connection accepted from %s"), *Endpoint.ToString());

	// Keep reading until there is no more data left on the socket
	while (Socket->HasPendingData(DataSize))
	{
		UE_LOG(LogTemp, Log, TEXT("TCP socket has %d bytes of pending data"), DataSize);

		// Read a single chunk of data from the socket
		if (Socket->Recv(Data, sizeof(Data), BytesRead))
		{
			UE_LOG(LogTemp, Log, TEXT("Received %d bytes from %s"), BytesRead, *Endpoint.ToString());

			// Convert the raw byte data in UTF-8 encoding to an FString, if that's what you want to do
			FUTF8ToTCHAR Converted(reinterpret_cast<const ANSICHAR*>(Data), BytesRead);
			UE_LOG(LogTemp, Log, TEXT("Received string: %s"), *FString(Converted.Length(), Converted.Get()));
		}
		else
		{
			UE_LOG(LogTemp, Warning, TEXT("Error receiving data from TCP socket!"));
		}
	}

	return true;
}


Thank you Nico de Poel for your post.
I used code sample you provided and it worked like miracle, i was finally able to receive expected data. Connection broke afterwards, but I’ll figure it out,
One more thing, probably not from this topic, but I am wondering if you could help with one more thing, or recomment some other post. I want to create standalone plugin, with tcp listener and i cant figure out, how to use actor classes (put them in actual game and make them work), which I created in plugin folders.

A quick question, is it possible to access the dev lan address on a PS4, i’m trying to setup some automation that requires a tcp connection.

Thanks

Hi Rama, Do you know if it is possible or how to connect to a PS4 Dev Lan, i’m trying to set up some automation software that requires this connection.

Thanks

Dave

TCP Receiver and Sender

Dear Unreal Community,

First of all thank you very much Rama for your great work!
Cause we’ve had some trouble with the TCP Connection between Unreal Engine and MATLAB we’ve extended (Sending feature) and did some changes to the RAMA Code
to work with the actual Unreal Engine and want to share the code with you. We used it inside an Actor Class - smarter would be a plugin … maybe there’s some time in the future.

It’s written quick & dirty any recommendations are welcome!

  1. Do not forget to Add the Dependencies in YourClassName.build.cs => AND right-click on the C++ Project File => Right-click on the .uproject file. => Select “Generate Visual Studio project files”. Re-open the Project (Unreal & VisualStudio) after before trying to compile!

PublicDependencyModuleNames.AddRange(new string] { "Core", "CoreUObject", "Engine", "InputCore", "Sockets", "Networking" });

  1. Header-File

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "GameFramework/Actor.h"
#include "Networking.h"
#include "MyActorTCP.generated.h"

UCLASS()
class VECTION_API AMyActorTCP : public AActor
{
	GENERATED_BODY()

public:
	// Sets default values for this actor's properties
	AMyActorTCP();

protected:
	// Called when the game starts or when spawned
	virtual void BeginPlay() override;
	virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;


public:
	// Called every frame
	virtual void Tick(float DeltaTime) override;
	FSocket* ListenerSocket;
	FSocket* ConnectionSocket;
	FIPv4Endpoint RemoteAddressForConnection;

	FTimerHandle TCPSocketListenerTimerHandle;
	FTimerHandle TCPConnectionListenerTimerHandle;

	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
		);

	//Timer functions, could be threads
	void TCPConnectionListener(); 	//can thread this eventually
	FString StringFromBinaryArray(TArray<uint8> BinaryArray);
	void TCPSocketListener();		//can thread this eventually


									//Format String IP4 to number array
	bool FormatIP4ToNumber(const FString& TheIP, uint8(&Out)[4]);

	UFUNCTION(BlueprintCallable, Category = "TCPServer")
		bool LaunchTCP();

	UFUNCTION(BlueprintCallable, Category = "TCPServer")
		void TCPSend(FString message);

	UFUNCTION(BlueprintImplementableEvent, Category = "TCPServer")
		void recievedMessage(const FString &message);
};


  1. CPP File

#include "Vection.h"
#include <string>
#include "MyActorTCP.h"


// Sets default values
AMyActorTCP::AMyActorTCP()
{
 	// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;

}

// Called when the game starts or when spawned
void AMyActorTCP::BeginPlay()
{
	Super::BeginPlay();
}

void AMyActorTCP::EndPlay(const EEndPlayReason::Type EndPlayReason)
{
	Super::EndPlay(EndPlayReason);
	UWorld* World = GetWorld();

	GetWorld()->GetTimerManager().ClearTimer(TCPConnectionListenerTimerHandle);
	GetWorld()->GetTimerManager().ClearTimer(TCPSocketListenerTimerHandle);

	if (ConnectionSocket != NULL) {
		ConnectionSocket->Close();
	}
	if (ListenerSocket != NULL) {
		ListenerSocket->Close();
	}

}

// Called every frame
void AMyActorTCP::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

}

// TCP Server Code
bool AMyActorTCP::LaunchTCP()
{
	if (!StartTCPReceiver("RamaSocketListener", "127.0.0.1", 62))
	{
		return false;
	}
	return true;
}

//Rama's Start TCP Receiver
bool AMyActorTCP::StartTCPReceiver(
	const FString& YourChosenSocketName,
	const FString& TheIP,
	const int32 ThePort
	) {
	//Rama's CreateTCPConnectionListener
	ListenerSocket = CreateTCPConnectionListener(YourChosenSocketName, TheIP, ThePort);

	//Not created?
	if (!ListenerSocket)
	{
		GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, FString::Printf(TEXT("StartTCPReceiver>> Listen socket could not be created! ~> %s %d"), *TheIP, ThePort));
		return false;
	}

	//Start the Listener! //thread this eventually


	UWorld* World = GetWorld();
	World->GetTimerManager().SetTimer(TCPConnectionListenerTimerHandle, this, &AMyActorTCP::TCPConnectionListener, 1.0f, true);
	GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, FString::Printf(TEXT("StartTCPReceiver>> Listen socket created")));
	return true;
}
//Format IP String as Number Parts
bool AMyActorTCP::FormatIP4ToNumber(const FString& TheIP, uint8(&Out)[4])
{
	//IP Formatting
	TheIP.Replace(TEXT(" "), TEXT(""));

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	//						   IP 4 Parts

	//String Parts
	TArray<FString> Parts;
	TheIP.ParseIntoArray(Parts, TEXT("."), true);
	if (Parts.Num() != 4)
		return false;

	//String to Number Parts
	for (int32 i = 0; i < 4; ++i)
	{
		Out* = FCString::Atoi(*Parts*);
	}

	return true;
}
//Rama's Create TCP Connection Listener
FSocket* AMyActorTCP::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;
	ListenSocket->SetReceiveBufferSize(ReceiveBufferSize, NewSize);

	//Done!
	return ListenSocket;
}
//Rama's TCP Connection Listener
void AMyActorTCP::TCPConnectionListener()
{

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

	// handle incoming connections
	ListenerSocket->HasPendingConnection(Pending);

	if (Pending)
	{
		//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
		//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);

			//can thread this too
			UWorld* World = GetWorld();

			World->GetTimerManager().SetTimer(TCPSocketListenerTimerHandle, this, &AMyActorTCP::TCPSocketListener, 0.1f, true);
		}
	}
}

//Rama's String From Binary Array
FString AMyActorTCP::StringFromBinaryArray(TArray<uint8> BinaryArray)
{

	//Create a string from a byte array!
	const std::string cstr(reinterpret_cast<const char*>(BinaryArray.GetData()), BinaryArray.Num());

	return FString(cstr.c_str());

	//BinaryArray.Add(0); // Add 0 termination. Even if the string is already 0-terminated, it doesn't change the results.
	// Create a string from a byte array. The string is expected to be 0 terminated (i.e. a byte set to 0).
	// Use UTF8_TO_TCHAR if needed.
	// If you happen to know the data is UTF-16 (USC2) formatted, you do not need any conversion to begin with.
	// Otherwise you might have to write your own conversion algorithm to convert between multilingual UTF-16 planes.
	//return FString(ANSI_TO_TCHAR(reinterpret_cast<const char*>(BinaryArray.GetData())));
}

void AMyActorTCP::TCPSend(FString ToSend) {
	ToSend = ToSend + LINE_TERMINATOR; //For Matlab we need a defined line break (fscanf function) "
" ist not working, therefore use the LINE_TERMINATOR macro form UE

	TCHAR *SerializedChar = ToSend.GetCharArray().GetData();
	int32 Size = FCString::Strlen(SerializedChar);
	int32 Sent = 0;
	uint8* ResultChars = (uint8*)TCHAR_TO_UTF8(SerializedChar);

	if (!ConnectionSocket->Send(ResultChars, Size, sent)) {
		GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, FString::Printf(TEXT("Error sending message")));
	}

}

//Rama's TCP Socket Listener
void AMyActorTCP::TCPSocketListener()
{
	//~~~~~~~~~~~~~
	if (!ConnectionSocket) return;
	//~~~~~~~~~~~~~


	//Binary Array!
	TArray<uint8> ReceivedData;

	uint32 Size;
	while (ConnectionSocket->HasPendingData(Size))
	{
		ReceivedData.Init(FMath::Min(Size, 65507u), Size);

		int32 Read = 0;
		ConnectionSocket->Recv(ReceivedData.GetData(), ReceivedData.Num(), Read);
	}
	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

	if (ReceivedData.Num() <= 0)
	{
		return;
	}

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	//						Rama's String From Binary Array
	const FString ReceivedUE4String = StringFromBinaryArray(ReceivedData);
	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	recievedMessage(ReceivedUE4String);

	GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, FString::Printf(TEXT("As String Data ~> %s"), *ReceivedUE4String));
}



@PHi.Wop

Thank you for sharing! I am linking your post in the wiki!

:heart:

Rama

Thank you for the code. I used your code and could get tcp connection in Unreal but still could not receive the data yet. I wrote the tcp sender script in python.



import socket

s = None

def openConnection(TCP_PORT=8888):
    TCP_IP = '127.0.0.1'
    BUFFER_SIZE = 1024
    global s

    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect((TCP_IP, TCP_PORT))

def sendMessage(MESSAGE):
    s.send(MESSAGE)

def closeConnection():
    s.close()


I tested by let my unreal project in play mode.
and in python


sender.openConnection(8888)

And I see “Connection accepted from …”

but when running


sender.sendMessage("ASdfsdf")

No log about received data. It looks like when tcp was connected, HandleConnectionAccepted was called and no data at that time yet. When receiving message, no callback is called.

Since I am new to tcp so not sure if I test it right.

I would appreciate if you could show your script for testing.

Thanks,
Zack

hi Rama,

Thanks very much for your great sharing.

I am using your code to receive data from H5 client and I can accept the connection but H5 client cannot shakehands successfully. Do you any idea? Am I miss something?

I wanted to mention that I referred to this thread in another ( Need a TCP Listener that works on 4.19 - C++ Gameplay Programming - Unreal Engine Forums ).
If anybody has a TCP Listener that 1. works in 4.19 and perhaps 2. Run on its own thread I would like to see the code. I have not been able to get any of the pieces of code working that were shared in this thread. Makes me wonder how things will go in 4.20 with all the changes.

Hello all.

I’ve been on a deep dive lately trying to learn the process of having two applications communicate with each other. All of this information is great and I am trying to process everything that’s been given. I have some questions that might seem basic. My main goal is to have the ability to execute python scripts from Maya to Unreal.

Is it possible to communicate to other software through unreal without a plugin? Does Unreal have a built in structure to utilize?

My first test is to send a simple HelloWorld.py from maya and try and get it over to Unreal. I would appreciate any pointers or feedback on how to approach this.

Thanks!

Is this supposed to work with later versions of the Engine? I am currently on 4.24 and trying to send one message/data from a client to another client.
“Networking.h” no longer seems to exist.
I have tried including Sockets.h, SocketSubsystem.h, Runtime/Networking/Public/Interfaces/IPv4/IPv4Address.h
Not having any luck with building the c++ code.