Below is my c++ in engine. It is very rough, I’m not using classes right and I could easily add multithreading like your tutorial.
FString UNetworkingFunctionLibrary::TestMsgToServer(const FString SocketName, const FString& ip, const int32 port, const FString message)
{
TSharedRef<FInternetAddr> RemoteAddress = ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->CreateInternetAddr();
TSharedRef<FInternetAddr> MyAddress = ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->CreateInternetAddr();
FSocket* SenderSocket;
int32 BufferSize = 1024;
bool bIsValid;
RemoteAddress->SetIp(*ip, bIsValid);
RemoteAddress->SetPort(port);
if (!bIsValid)
{
/*GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Yellow, TEXT("Not Valid IP"));*/
return FString("IP Not Valid");
}
// Create the socket.
SenderSocket = ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->CreateSocket(FName(NAME_DGram), TEXT("TCP Server Test"));
SenderSocket->SetSendBufferSize(BufferSize, BufferSize);
SenderSocket->SetReceiveBufferSize(BufferSize, BufferSize);
SenderSocket->SetNonBlocking(true);
//FString serialized = message;
//TCHAR *serializedChar = serialized.GetCharArray().GetData();
int32 sent = 0;
bool successful = SenderSocket->SendTo((uint8*)TCHAR_TO_UTF8(*message), sizeof(message), sent, *RemoteAddress);
if (!successful)
{
return FString("Send Not Successful");
SenderSocket->Close();
}
TArray<uint8> ReceivedData;
TSharedRef<FInternetAddr> ReceivedAddr = ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->CreateInternetAddr();
uint32 Size;
bool bIsDataReceived = false;
while (!bIsDataReceived)
{
if (SenderSocket->HasPendingData(Size))
{
ReceivedData.Init(FMath::Min(Size, 65507u));
int32 Read = 0;
SenderSocket->RecvFrom(ReceivedData.GetData(), BufferSize, Read, *ReceivedAddr);
if (Read > 0)
{
bIsDataReceived = true;
}
}
}
SenderSocket->Close();
return StringFromBinaryArray(ReceivedData);
}
FString UNetworkingFunctionLibrary::StringFromBinaryArray(const TArray<uint8>& BinaryArray)
{
//Create a string from a byte array!
const std::string cstr(reinterpret_cast<const char*>(BinaryArray.GetData()), BinaryArray.Num());
//FString can take in the c_str() of a std::string
return FString(cstr.c_str());
}
Below is my 3 seperate python scripts that run my server in its very rough test state.
Main Server code
##################################
## UDP Server to Talk to UE4
##################################
### Imports
import socket
import sys
from UDPRequestHandler import *
HOST = 'localhost'
PORT = 8800
# Create the UDP Socket
try:
socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
print("Socket Created")
except socket.error:
print("Failed to create socket.")
sys.exit()
# Bind socket to local host and port
try:
socket.bind((HOST, PORT))
except:
print("Bind failed.")
sys.exit()
print("Socket bind complete.")
# Now keep talking to clients
while 1:
# Receive data from client (data, addr)
d = socket.recvfrom(1024)
data = d[0]
addr = d[1]
# Print to the server who made a connection.
print("{} wrote:".format(addr))
print(data)
# Now have our UDP handler handle the data
myUDPHandler = UDPRequestHandler()
myResponse = myUDPHandler.handle(data)
# Respond back
print(myResponse)
socket.sendto(bytes(myResponse, 'utf-8'), addr)
socket.close()
Handler Class
########################
## TCPHandler Class
########################
### Imports
import socketserver
import json
from passlib.hash import pbkdf2_sha256
from UDPPostgreSQLConnector import *
class UDPRequestHandler:
def checkLogin(self, email, password):
# This checks to see if the player is who they say they are.
# If so send back a dict with the players ID and remember_token.
myDB = TCPPostgreSQLConnector()
pswdToCheck = pbkdf2_sha256.encrypt(password, rounds=200000,
salt_size=16)
dbResponse = myDB.selectWhere("virtualtabletop.players",
"*", "email = '" + email + "'")
if (pbkdf2_sha256.verify(password, dbResponse['password'])):
return "Logged In"
else:
return "Invalid Password"
def handle(self, data):
myData = str(data.strip())
if myData == 'Login':
ResponseStr = "{'Return': " + self.checkLogin(data['Email'],
data['Password'])
elif myData == 'Test':
ResponseStr = pbkdf2_sha256.encrypt(data['Password'], rounds=5000,
salt_size=16)
else:
ResponseStr = "I hear you"
response = ResponseStr
return response
And my Database code. Import stuff like ips and passwords removed.
#######################
## PostgreSQL Class
#######################
import psycopg2 as mdb
import psycopg2.extras
import sys
class UDPPostgreSQLConnector:
connection = None
host = 'secret'
port = secret
dbUser = 'secret'
dbPassword = 'secret'
db = 'secret'
def openConnection(self, db):
conString = "host='secret' dbname='secret' user='secret' password='secret'"
# opens a connection to the db
self.connection = mdb.connect(conString)
def closeConnection(self):
#Closes the connection
self.connection.close()
def selectWhere(self, table, columns, where):
# Use like
#selectWhere("users", "id", "email='lll'")
try:
self.openConnection(self.db)
cur = self.connection.cursor(cursor_factory=mdb.extras.RealDictCursor)
cur.execute("SELECT " + columns + " FROM " + table +
" WHERE " + where)
data = cur.fetchone()
if (data == ""):
data = "No users."
cur.close()
except mdb.DatabaseError as e:
data = 'Error %s' % e
#sys.exit(1)
finally:
if self.connection:
self.closeConnection()
return data