Download

Finally working UDP Sockets Message Receiving Tutorial

Hello.

After long time trying to make UDP sockets working I made it just by luck today!

At first thing i want to say thanks to 1 guy who solved 1 thing with UDP

https://answers.unrealengine.com/questions/253988/udp-recvfrom-using-fsocket.html

Well it’s not maybe something pretty advanced but it’s working.
So far i was testing it on 127.0.0.1 and 192.168.x.x but i think on public IP it should work too[Not sure about ports, just open 1 port UDP, in my is 5000 for example]

There is my CPP file



#include "PluginMaking.h"
#include "ServerListener.h"
#include <string>
#include "Runtime/Core/Public/Misc/Base64.h"


// Sets default values
AServerListener::AServerListener(const FObjectInitializer& ObjectInitializer)
	: Super(ObjectInitializer)
{
 	// 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;
}

void AServerListener::EndPlay(const EEndPlayReason::Type EndPlayReason)
{
	Super::EndPlay(EndPlayReason);
	//~~~~~~~~~~~~~~~~
}

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

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

	FIPv4Endpoint Endpoint(FIPv4Address::Any, 5000);

	ListenSocket = FUdpSocketBuilder(TEXT("SomeDescription"))
		.AsNonBlocking()
		.AsReusable()
		.BoundToEndpoint(Endpoint)
		.WithReceiveBufferSize(2 * 1024 * 1024);

	int32 SendSize = 2 * 1024 * 1024;
	ListenSocket->SetSendBufferSize(SendSize, SendSize);
	ListenSocket->SetReceiveBufferSize(SendSize, SendSize);
	
}

void AServerListener::Callback(const FArrayReaderPtr& data, const FIPv4Endpoint&) {

	const auto encoded = FBase64::Encode(*data);
	GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, encoded);
	UE_LOG(LogTemp, Verbose, TEXT("Received: %s"), *encoded);
}

void AServerListener::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

	TSharedRef<FInternetAddr> targetAddr = ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->CreateInternetAddr();
	//GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, "Dostalem wiadomosc yaay ");
	TArray<uint8> ReceivedData;

	uint32 Size;
	while (ListenSocket->HasPendingData(Size))
	{
		uint8 *Recv = new uint8[Size];
		int32 BytesRead = 0;

		ReceivedData.SetNumUninitialized(FMath::Min(Size, 65507u));

		ListenSocket->RecvFrom(ReceivedData.GetData(), ReceivedData.Num(), BytesRead, *targetAddr);
		//Do something with the received data

		char ansiiData[1024]; //A temp buffer for the data

		memcpy(ansiiData, ReceivedData.GetData(), BytesRead); //Assumes bytesRead is always smaller than 1024 bytes

		ansiiData[BytesRead] = 0; //Add null terminator

		FString debugData = ANSI_TO_TCHAR(ansiiData);

		//ListenSocket->RecvFrom(Recv, Size, BytesRead, *targetAddr);

		GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, "Message by UDP: " + debugData);
	}
}

Just change anything you need to your settings it’s free to use.

And there is .h file



#pragma once

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

UCLASS()
class PLUGINMAKING_API AServerListener : public AActor
{
	GENERATED_UCLASS_BODY()
	
public:

	//====================================================

public:
	FSocket* ListenSocket;

	FUdpSocketReceiver* mySocketReceiver;

	virtual void BeginPlay() override;

	virtual void Tick(float DeltaSeconds) override;

	//ScreenMsg
	FORCEINLINE void ScreenMsg(const FString& Msg)
	{
		GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, *Msg);
	}
	FORCEINLINE void ScreenMsg(const FString& Msg, const float Value)
	{
		GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, FString::Printf(TEXT("%s %f"), *Msg, Value));
	}
	FORCEINLINE void ScreenMsg(const FString& Msg, const FString& Msg2)
	{
		GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, FString::Printf(TEXT("%s %s"), *Msg, *Msg2));
	}


public:

	void Callback(const FArrayReaderPtr& data, const FIPv4Endpoint&);

	/** Called whenever this actor is being removed from a level */
	virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
};


There are some old codes from Rama Code just remove it if u want.

Thanks for any feedbacks and likes :slight_smile:

Will try to update this thread as much as i can!

#1 Updated message encoding.
#2 Tested at public IP and works.

Made UDP Hole Punching :slight_smile:

Tutorial will be soon.

Hole Punching is easy :smiley:
Great Post! Im looking into this for ages and got it working as well, but any other implementation is something i can learn from.
If you want to do a good deed, then expose this with blueprints with an OnUDPReceived event :wink:

Did you have that tutorial or some hint that you could give to me to do Hole Punching? I’m trying to do a basic matchmaking with Hole Punching but I’m kinda lost on that