Local UDP broadcast with FSocket

HI ,
It’s not mandatory use 2 computers for debugging, you can test with your own, by connecting sockets with self connection 127.0.0.1
I made that example some time ago, I connect my little toy car with arduino and my cel phone and yeah!!, I use UDP sockets.

take a look:

I create a simple class inheriting from UActorComponent with few methods inside, I share you:

my header:



#pragma once
#include "Networking.h"
#include "Engine.h"
#include "SocketPower.Generated.h"

USTRUCT(BlueprintType)
struct FAnyCustomData
{
	GENERATED_USTRUCT_BODY()

		UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "DATA")
		float motor = 0;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "DATA")
		float servo = 0;

	FAnyCustomData()
	{}
};

FORCEINLINE FArchive& operator<<(FArchive &Ar, FAnyCustomData& TheStruct)
{
	Ar << TheStruct.motor;
	Ar << TheStruct.servo;
	return Ar;
}

DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FGetReceivedData, const FAnyCustomData&, receivedData);

UCLASS(meta = (BlueprintSpawnableComponent), ClassGroup = (Hardware))
class USocketPower : public UActorComponent
{
	GENERATED_BODY()

private:
	bool isServer = false;
	FSocket* socket;
	FUdpSocketReceiver* UDPReceiver = nullptr;
	FAnyCustomData dataRev;

public:

	TSharedPtr<FInternetAddr>	RemoteAddr;

	UPROPERTY(BlueprintAssignable)
		FGetReceivedData OnSuccess;

	UFUNCTION(BlueprintPure, Category = "Internet")
		FAnyCustomData getDataRev();

	UFUNCTION(BlueprintCallable, Category = "Internet")
		bool sendData(FAnyCustomData data);

	UFUNCTION(BlueprintCallable, Category = "Internet")
		bool tryToConnect(FString socketname, FString IP, int32 port, bool UDP = false);

	UFUNCTION(BlueprintCallable, Category = "Internet")
		bool startServer(FString socketname, FString IP, int32 port);

	UFUNCTION(BlueprintCallable, Category = "Internet")
		void closeConnection();

	void Recv(const FArrayReaderPtr& ArrayReaderPtr, const FIPv4Endpoint& EndPt);

};


my cpp:



#include "SocketFuncPrivatePCH.h"
#include "SocketPower.h"

bool USocketPower::startServer(FString socketname, FString IP, int32 port)
{
	FIPv4Address Addr;
	FIPv4Address::Parse(IP, Addr);

	//Create Socket
	FIPv4Endpoint Endpoint(Addr, port);

	//BUFFER SIZE
	int32 BufferSize = 2 * 1024 * 1024;

	socket = FUdpSocketBuilder(*socketname)
		.AsNonBlocking()
		.AsReusable()
		.BoundToEndpoint(Endpoint)
		.WithReceiveBufferSize(BufferSize);
	;

	FTimespan ThreadWaitTime = FTimespan::FromMilliseconds(100);
	UDPReceiver = new FUdpSocketReceiver(socket, ThreadWaitTime, TEXT("UDP RECEIVER"));
	UDPReceiver->OnDataReceived().BindUObject(this, &USocketPower::Recv);

	if (socket)
	{
		isServer = true;
	}
	return isServer;
}

bool USocketPower::tryToConnect(FString socketname, FString IP, int32 port, bool UDP)
{
	RemoteAddr = ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->CreateInternetAddr();
	bool bIsValid;
	RemoteAddr->SetIp(*IP, bIsValid);
	RemoteAddr->SetPort(port);

	if (!bIsValid)
	{
		GEngine->AddOnScreenDebugMessage(-1,3,FColor::Red,"IP address was not valid!");
		return false;
	}

	socket = FUdpSocketBuilder(*socketname).AsReusable().WithBroadcast();
	//Set Send Buffer Size
	int32 SendSize = 2 * 1024 * 1024;
	socket->SetSendBufferSize(SendSize, SendSize);
	socket->SetReceiveBufferSize(SendSize, SendSize);

	if (socket)
	{
		return true;
	}

	return false;
}

bool USocketPower::sendData(FAnyCustomData data)
{
	if (!socket || isServer)
	{
		GEngine->AddOnScreenDebugMessage(-1, 3, FColor::Red, "no sender socket");
		return false;
	}

	FArrayWriter Writer;
	Writer << data;
	int32 BytesSent = 0;
	socket->SendTo(Writer.GetData(), Writer.Num(), BytesSent, *RemoteAddr);
	if (BytesSent <= 0)
	{
		GEngine->AddOnScreenDebugMessage(-1, 3, FColor::Red, "invalid send");
		return false;
	}

	return true;
}

void USocketPower::closeConnection()
{
	if (UDPReceiver)
	{
		delete UDPReceiver;
		UDPReceiver = nullptr;
	}

	if (socket)
	{
		socket->Close();
		ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->DestroySocket(socket);
	}
	
}

void USocketPower::Recv(const FArrayReaderPtr& ArrayReaderPtr, const FIPv4Endpoint& EndPt)
{
	FAnyCustomData Data;
	*ArrayReaderPtr << Data;
	FAnyCustomData copy;
	copy.motor = Data.motor;
	copy.servo = Data.servo;
	dataRev = copy;
}

FAnyCustomData USocketPower::getDataRev()
{
	return dataRev;
}


It’s super simple, I think is enough clear, but if you have some troubles, let me know

Cheers!