Game as Socket Server

Hey All,

I am CEO of a company that does simulations. I have put 3 engineers on this task and all have failed. I have placed a bet that my dumb CEO butt can figure this out before they can. If I get this written and checked in before they do, I get to hang embarrassing posters in their offices for a month.

I know limited C++ and Unreal Engine 4. I was a unity dev and a.i. researcher once upon a time. If anybody can help me get this rolled out, that would be awesome. I need to set it up so that my Unreal Game is a socket server that I can connect to from a python application (random python application). The game will send me data on a trigger and I can send it data. When it receives data, it does something, who cares, turns a box red. I just need bi-directional communication between the two.

Data shipping out of the unreal game will be primarily soured from a class that extends SceneCapture2D shipping out the pixel data at 30-60 fps along with some meta data. Data coming in will be very light.

Any assistance is greatly appreciated. I just need to get a functional P.O.C. to win the bet.

try Unreal Messaging:

Hrm, the closest I could find to what I want is this:,Receive_Binary_Data_From_an_IP/Port_Into_UE4,(Full_Code_Sample)

Unfortunately it doesn’t appear to work. I can’t get my client to connect. Here is some sample client code. Its python 3.5

import socket
import time

client code

def openConnection(TCP_PORT=8423):
TCP_IP = ‘’

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
if s.connect_ex((TCP_IP, TCP_PORT)):
return s

def sendMessage(s, MESSAGE):

def receiveMessage(s):
data_raw = s.recv(BUFFER_SIZE)
data = data_raw.decode(“utf-8”)
print("client received data: " + data)
return data_raw

def closeConnection(s):

if name == ‘main’:
socket = openConnection()
if(socket == None):
print(“failed to create”)
sendMessage(socket, “Testing Connection”.encode(“utf-8”))
#data = s.recv(1024)
# print ‘Received’, repr(data)

Actually I’m able to get it to work, but only on the first launch and connection. If I leave the game running and attempt to connect to the game again, it fails. The client says “Connected”, however it appears the game does not register the problem. I can stop the game in the view port, and restart it, launch the client code. The client will register a connection and that it sent something, however the game will not register anything was received.

EDIT: GOT IT WORKING, putting modified listening code below

Last item I need to figure out is how to send data to a connected client on the socket.

//// Fill out your copyright notice in the Description page of Project Settings.
#include “RoboSimStudio.h”
#include “NetworkActor.h”
#include <string>
//// Sets default values
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don’t need it.
PrimaryActorTick.bCanEverTick = false;
//// Called when the game starts or when spawned
void ANetworkActor::BeginPlay()
//IP =, Port = 8890 for my Python test case
if (!StartTCPReceiver(“RamaSocketListener”, “”, 8423))
UE_LOG(LogTemp, Warning, TEXT(“TCP Socket Listener Failed!”));
//// Called every frame
void ANetworkActor::Tick( float DeltaTime )
Super::Tick( DeltaTime );
//Rama’s Start TCP Receiver
bool ANetworkActor::StartTCPReceiver(
const FString& YourChosenSocketName,
const FString& TheIP,
const int32 ThePort
//Rama’s CreateTCPConnectionListener
ListenerSocket = CreateTCPConnectionListener(YourChosenSocketName, TheIP, ThePort);

//Not created?
if (!ListenerSocket)
	UE_LOG(LogTemp, Error, TEXT("StartTCPReceiver&gt;&gt; Listen socket could not be created! ~&gt; %s %d"), *TheIP, ThePort);
	return false;
UE_LOG(LogTemp, Warning, TEXT("StartTCPReceiver&gt;&gt; Listen socket created! ~&gt; %s %d"), *TheIP, ThePort);

//TODO: Start the Listener! //thread this eventually
GetWorldTimerManager().SetTimer(ConnectionListenTimer, this, &ANetworkActor::TCPConnectionListener, 0.01f, true);

return true;

//Format IP String as Number Parts
bool ANetworkActor::FormatIP4ToNumber(const FString& TheIP, uint8(&Out)[4])
//IP Formatting
TheIP.Replace(TEXT(" “), TEXT(”"));
const TCHAR *delim;
delim = TEXT(".");

TArray&lt;FString&gt; Parts;
TheIP.ParseIntoArray(Parts, delim, true);
if (Parts.Num() != 4)
	return false;

for (int32 i = 0; i &lt; 4; ++i)
	Out* = FCString::Atoi(*Parts*);
return true;

//Rama’s Create TCP Connection Listener
FSocket* ANetworkActor::CreateTCPConnectionListener(const FString& YourChosenSocketName, const FString& TheIP, const int32 ThePort, const int32 ReceiveBufferSize)
uint8 IP4Nums[4];
if (!FormatIP4ToNumber(TheIP, IP4Nums))
UE_LOG(LogTemp, Error, TEXT(“Invalid IP! Expecting 4 parts separated by .”));
return false;
//Create Socket
FIPv4Endpoint Endpoint(FIPv4Address(IP4Nums[0], IP4Nums[1], IP4Nums[2], IP4Nums[3]), ThePort);
FSocket* ListenSocket = FTcpSocketBuilder(*YourChosenSocketName)
//Set Buffer Size
int32 NewSize = 0;
ListenSocket->SetReceiveBufferSize(ReceiveBufferSize, NewSize);
return ListenSocket;
//Rama’s TCP Connection Listener
void ANetworkActor::TCPConnectionListener()
//UE_LOG(LogTemp, Warning, TEXT(“Checking socket…”));
if (!ListenerSocket)
UE_LOG(LogTemp, Error, TEXT(“Listener doesn’t exist, but should.”));

//Remote address
TSharedRef&lt;FInternetAddr&gt; RemoteAddress = ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)-&gt;CreateInternetAddr();
bool Pending;

// handle incoming connections
if (ListenerSocket-&gt;HasPendingConnection(Pending) && Pending)
	UE_LOG(LogTemp, Warning, TEXT("Connection Pending..."));
	//Already have a Connection? destroy previous
	if (ConnectionSocket)
	//New Connection receive!
	ConnectionSocket = ListenerSocket-&gt;Accept(*RemoteAddress, TEXT("TODO: Start Kick off Event"));

	if (ConnectionSocket != NULL)
		//Global cache of current Remote Address
		RemoteAddressForConnection = FIPv4Endpoint(RemoteAddress);
		//UE_LOG "Accepted Connection! WOOOHOOOO!!!";
		UE_LOG(LogTemp, Warning, TEXT("Accepted Connection!"));
		//can thread this too
		GetWorldTimerManager().SetTimer(SocketListenTimer, this, &ANetworkActor::TCPSocketListener, 0.01f, true);


FString ANetworkActor::StringFromBinaryArray(const TArray<uint8>& BinaryArray)
//Create a string from a byte array!
std::string cstr(reinterpret_cast<const char*>(BinaryArray.GetData()), BinaryArray.Num());
return FString(cstr.c_str());

//Rama’s TCP Socket Listener
void ANetworkActor::TCPSocketListener()
if (!ConnectionSocket) return;

//Binary Array!
TArray&lt;uint8&gt; ReceivedData;
uint32 Size;
while (ConnectionSocket-&gt;HasPendingData(Size))
	ReceivedData.Init(0.0f, FMath::Min(Size, 65507u));

	int32 Read = 0;
	ConnectionSocket-&gt;Recv(ReceivedData.GetData(), ReceivedData.Num(), Read);

	UE_LOG(LogTemp, Warning, TEXT("Data Read! %d"), ReceivedData.Num());
if (ReceivedData.Num() &lt;= 0)
	//No Data Received
const FString ReceivedUE4String = StringFromBinaryArray(ReceivedData);
UE_LOG(LogTemp, Warning, TEXT("Total Data read! %d"), ReceivedData.Num());
UE_LOG(LogTemp, Warning, TEXT("As String!!!!! ~&gt; %s"), *ReceivedUE4String);