1.確保工程為C++工程,在項目工程的xx.Build.cs中加入Networking和Sockets模塊。
PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "Networking", "Sockets"});
2.C++創建Actor,命名為UDPClient。
3.編寫代碼UDPClient.h和UDPClient.cpp實現UDP發送和接收功能。
// Fill out your copyright notice in the Description page of Project Settings.#pragma once#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "Runtime/Sockets/Public/Sockets.h"
#include "Sockets/Public/SocketSubsystem.h"
#include "Runtime/Networking/Public/Common/UdpSocketBuilder.h"
#include "Runtime/Networking/Public/Common/UdpSocketReceiver.h"
#include "Networking/Public/Interfaces/IPv4/IPv4Address.h"
#include "UDPClient.generated.h"UCLASS()
class MYBLANK_API AUDPClient : public AActor
{GENERATED_BODY()public: // Sets default values for this actor's propertiesAUDPClient();protected:// Called when the game starts or when spawnedvirtual void BeginPlay() override;virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;public: // Called every framevirtual void Tick(float DeltaTime) override;public:FSocket* udpSocket;//遠程的地址TSharedPtr<FInternetAddr> RemoteAddr;UFUNCTION(BlueprintCallable, Category = "UDP")bool CreateUdp(const FString& socketName, const FString& targetIP, const int32 targetPort, const int32 selfPort);UFUNCTION(BlueprintCallable, Category = "UDP")bool SendMsg(FString msg);UFUNCTION(BlueprintCallable, Category = "UDP")void RecvMsg(bool& result, FString& msg);};
// Fill out your copyright notice in the Description page of Project Settings.#include "UDPClient.h"// Sets default values
AUDPClient::AUDPClient()
{// 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;udpSocket = NULL;
}// Called when the game starts or when spawned
void AUDPClient::BeginPlay()
{Super::BeginPlay();}// Called every frame
void AUDPClient::Tick(float DeltaTime)
{Super::Tick(DeltaTime);}void AUDPClient::EndPlay(const EEndPlayReason::Type EndPlayReason)
{Super::EndPlay(EndPlayReason);if (udpSocket){udpSocket->Close();ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->DestroySocket(udpSocket);}
}bool AUDPClient::CreateUdp(const FString& socketName, const FString& targetIP, const int32 targetPort, const int32 selfPort)
{bool bIsValid;RemoteAddr = ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->CreateInternetAddr();RemoteAddr->SetIp(*targetIP, bIsValid);RemoteAddr->SetPort(targetPort);if (!bIsValid){UE_LOG(LogTemp, Warning, TEXT("CreateUdp>> IP address was not valid! "), *targetIP);return false;}int32 BufferSize = 2 * 1024 * 1024;FIPv4Endpoint Endpoint(FIPv4Address::Any, selfPort); //所有ip地址本地udpSocket = FUdpSocketBuilder(*socketName).AsReusable().WithBroadcast() // 廣播.WithSendBufferSize(BufferSize).AsNonBlocking().BoundToEndpoint(Endpoint).WithReceiveBufferSize(BufferSize);udpSocket->SetSendBufferSize(BufferSize, BufferSize);udpSocket->SetReceiveBufferSize(BufferSize, BufferSize);return bIsValid;
}bool AUDPClient::SendMsg(FString msg)//發送消息
{if (!udpSocket){UE_LOG(LogTemp, Warning, TEXT("No udpSocket"));return false;}int32 BytesSent = 0;FString serialized = msg;TCHAR* serializedChar = serialized.GetCharArray().GetData();int32 size = FCString::Strlen(serializedChar);int32 sent = 0;udpSocket->SendTo((uint8*)TCHAR_TO_UTF8(serializedChar), size, BytesSent, *RemoteAddr);if (BytesSent < 0){const FString Str = "Socket is valid but the receiver received 0 bytes, make sure it is listening properly!";UE_LOG(LogTemp, Error, TEXT("%s"), *Str);return false;}UE_LOG(LogTemp, Warning, TEXT("SendMsg Succcess! INFO msg = %s "), *msg);return true;
}void AUDPClient::RecvMsg(bool& result,FString& msg)//接收消息
{if (!udpSocket){UE_LOG(LogTemp, Warning, TEXT("No udpSocket"));result = false;}TSharedRef<FInternetAddr> targetAddr = ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->CreateInternetAddr();TArray<uint8> ReceivedData;//定義一個接收器uint32 Size;if (udpSocket->HasPendingData(Size)){result = true;msg = "";uint8* Recv = new uint8[Size];int32 BytesRead = 0;ReceivedData.SetNumUninitialized(FMath::Min(Size, 65507u));udpSocket->RecvFrom(ReceivedData.GetData(), ReceivedData.Num(), BytesRead, *targetAddr);//創建遠程接收地址char ansiiData[1024];memcpy(ansiiData, ReceivedData.GetData(), BytesRead);//拷貝數據到接收器ansiiData[BytesRead] = 0; //判斷數據結束FString debugData = UTF8_TO_TCHAR(ansiiData); //字符串轉換msg = debugData;}else{result = false;}
}
FUdpSocketBuilder?Functions介紹: