?客戶端.h
需要在Build.cs中加入模塊:"Networking","Sockets","Json","JsonUtilities"文章來源:http://www.zghlxwxcb.cn/news/detail-800412.html
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "ClientActorClass.generated.h"
UCLASS()
class TCPSERVERANDCLIENT_API AClientActorClass : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
AClientActorClass();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
static FSocket* Socket;
//"Networking","Sockets"
UFUNCTION(BlueprintCallable,Category = "TCPServerAndClient")
static bool ClientConnectToTCPServer(const FString& IP,int32 Port = 8888);
UFUNCTION(BlueprintCallable,Category = "TCPServerAndClient")
static bool SendDataFormClicentToServer(TArray<uint8> SendData);
UFUNCTION(BlueprintCallable,Category = "TCPServerAndClient")
static bool DisConnectFormClientToServer();
UFUNCTION(BlueprintCallable,Category = "TCPServerAndClient")
static TArray<uint8> ReceiveDataFromTCPServer();
//"Json","JsonUtilities"
UFUNCTION(BlueprintCallable,Category = "TCPServerAndClient")
static void StringToBytes(FString InString,bool& OutBool,TArray<uint8>& OutBytesArray);
UFUNCTION(BlueprintCallable,Category = "TCPServerAndClient")
static void DataTypeToJSON(int32 Int,bool Inbool,FString String,FVector Vector,TArray<int32> Array,bool& OutBool,TArray<uint8>& OutBytesArray);
UFUNCTION(BlueprintCallable,Category = "TCPServerAndClient")
static void BytesToString(TArray<uint8> InBytesArray,FString& OutString);
};
?客戶端.cpp文章來源地址http://www.zghlxwxcb.cn/news/detail-800412.html
// Fill out your copyright notice in the Description page of Project Settings.
#include "ClientActorClass.h"
#include "Sockets.h"
#include "Internationalization/Text.h"
#include "Misc/OutputDevice.h"
#include "Internationalization/Internationalization.h"
#include "Common/TcpSocketBuilder.h"
FSocket* AClientActorClass::Socket = nullptr;
// Sets default values
AClientActorClass::AClientActorClass()
{
// 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;
}
// Called when the game starts or when spawned
void AClientActorClass::BeginPlay()
{
Super::BeginPlay();
}
// Called every frame
void AClientActorClass::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
bool AClientActorClass::ClientConnectToTCPServer(const FString& IP, int32 Port)
{
if (Socket)
{
Socket->Close();
ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->DestroySocket(Socket);
Socket = nullptr;
}
TSharedPtr<FInternetAddr> Addr = ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->CreateInternetAddr();
bool bIsValid;
Addr->SetIp(*IP,bIsValid);
Addr->SetPort(Port);
if (!bIsValid)
{
UE_LOG(LogTemp,Log,TEXT("InValid IP Address"));
GEngine->AddOnScreenDebugMessage(-1,5.0f,FColor::Red,TEXT("InValid IP Address"));
return false;
}
Socket = FTcpSocketBuilder(TEXT("TcpClient")).AsBlocking().WithReceiveBufferSize(2*1024*1024);
bool bConnected = Socket->Connect(*Addr);
if (!bConnected)
{
UE_LOG(LogTemp,Log,TEXT("Failed Connect To Server"));
GEngine->AddOnScreenDebugMessage(-1,5.0,FColor::Green,TEXT("Failed Connect To Server"));
return false;
}
UE_LOG(LogTemp,Log,TEXT("Success Connect To Server"));
GEngine->AddOnScreenDebugMessage(-1,5.0,FColor::Green,TEXT("Success Connect To Server"));
return true;
}
bool AClientActorClass::SendDataFormClicentToServer(TArray<uint8> SendData)
{
if (!Socket)
{
UE_LOG(LogTemp, Log, TEXT("Socket is not connected!"));
return false;
}
// 發(fā)送數(shù)據(jù)部分
int32 SentBytes = 0;
bool bSuccess = Socket->Send(SendData.GetData(), SendData.Num(), SentBytes);
if (!bSuccess || SentBytes != SendData.Num())
{
UE_LOG(LogTemp, Log, TEXT("Failed to send data!"));
return false;
}
GEngine->AddOnScreenDebugMessage(-1,5.0,FColor::Green,TEXT("Success to send data!"));
UE_LOG(LogTemp, Log, TEXT("Success to send data!"));
return true;
}
bool AClientActorClass::DisConnectFormClientToServer()
{
if (Socket)
{
Socket->Close();
ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->DestroySocket(Socket);
Socket = nullptr;
return true;
}
return false;
}
TArray<uint8> AClientActorClass::ReceiveDataFromTCPServer()
{
TArray<uint8> Bytes;
if (Socket)
{
uint32 Size;
while (Socket->HasPendingData(Size))
{
Bytes.SetNumUninitialized(FMath::Min(Size, 65507u));
int32 ReadBytes = 0;
// 讀取數(shù)據(jù)到字節(jié)流中
Socket->Recv(Bytes.GetData(), Bytes.Num(), ReadBytes);
// 將實際讀取的部分截取出來
Bytes.SetNum(ReadBytes);
// 如果需要等待接收完整數(shù)據(jù)再返回,可以設置一個條件,比如接收到特定結束標志
// 如果已經接收到完整數(shù)據(jù),可以直接返回
return Bytes;
}
}
// 如果沒有接收到數(shù)據(jù),返回空字節(jié)流
return TArray<uint8>();
}
void AClientActorClass::StringToBytes(FString InString, bool& OutBool, TArray<uint8>& OutBytesArray)
{
OutBytesArray.Empty();
if (!InString.IsEmpty())
{
FTCHARToUTF8 Converter(*InString);
int32 NumBytes = Converter.Length();
if (NumBytes > 0)
{
OutBytesArray.Append((uint8*)Converter.Get(), NumBytes);
OutBool = true;
}
else
{
OutBool = false;
}
}
else
{
OutBool = false;
}
}
void AClientActorClass::DataTypeToJSON(int32 Int, bool Inbool, FString String, FVector Vector, TArray<int32> Array,
bool& OutBool, TArray<uint8>& OutBytesArray)
{
OutBytesArray.Empty();
TSharedPtr<FJsonObject> JsonObject = MakeShareable(new FJsonObject);
JsonObject->SetNumberField("MyInteger",Int);
JsonObject->SetBoolField("MyBool",Inbool);
JsonObject->SetStringField("MyString",String);
TSharedPtr<FJsonObject> VectorObject = MakeShareable(new FJsonObject);
JsonObject->SetNumberField("MyVector",Vector.X);
JsonObject->SetNumberField("MyVector",Vector.Y);
JsonObject->SetNumberField("MyVector",Vector.Z);
JsonObject->SetObjectField("MyVector",VectorObject);
TArray<TSharedPtr<FJsonValue>> JsonArray;
for (auto& value : Array)
{
JsonArray.Add(MakeShareable(new FJsonValueNumber(value)));
}
JsonObject->SetArrayField("Array",JsonArray);
// 將 JSON 對象轉換為字符串
FString OutputString;
TSharedRef<TJsonWriter<>> Writer = TJsonWriterFactory<>::Create(&OutputString);
if (FJsonSerializer::Serialize(JsonObject.ToSharedRef(), Writer))
{
Writer->Close();
// 將字符串轉換為字節(jié)數(shù)組
FTCHARToUTF8 Converter(*OutputString);
int32 NumBytes = Converter.Length();
if (NumBytes > 0)
{
OutBytesArray.Append((uint8*)Converter.Get(), NumBytes);
OutBool = true;
}
else
{
OutBool = false;
}
}
else
{
OutBool = false;
}
}
void AClientActorClass::BytesToString(TArray<uint8> InBytesArray, FString& OutString)
{
// 檢查字節(jié)數(shù)組是否為空
if (InBytesArray.Num() == 0)
{
OutString.Empty();
GEngine->AddOnScreenDebugMessage(-1, 2.0, FColor::Blue, TEXT("data = null"));
UE_LOG(LogTemp, Log, TEXT("data = null"));
return;
}
// 將字節(jié)流轉換為UTF-8字符串
FString Utf8String = FUTF8ToTCHAR(reinterpret_cast<const ANSICHAR*>(InBytesArray.GetData()), InBytesArray.Num()).Get();
// 在這里你可以使用Utf8String進行其他操作,例如將其轉換為JSON對象
// 注意:在UE5中,你可能需要使用FJsonSerializer的Deserialize方法
TSharedPtr<FJsonObject> JsonObject;
TSharedRef<TJsonReader<>> Reader = TJsonReaderFactory<>::Create(Utf8String);
// Deserialize JSON
if (FJsonSerializer::Deserialize(Reader, JsonObject))
{
// 在這里可以使用JsonObject進行其他操作
}
else
{
// JSON解析失敗的處理
UE_LOG(LogTemp, Error, TEXT("Failed to parse JSON from string"));
}
// 將最終的JSON字符串賦值給輸出參數(shù)
OutString = Utf8String;
}
到了這里,關于UE5 C++的TCP服務器與客戶端的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!