UE5 C++的TCP服务器与客户端
创始人
2024-09-26 05:47:24
0

 客户端.h

需要在Build.cs中加入模块:"Networking","Sockets","Json","JsonUtilities"

// 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 SendData);  	UFUNCTION(BlueprintCallable,Category = "TCPServerAndClient") 	static bool DisConnectFormClientToServer();  	UFUNCTION(BlueprintCallable,Category = "TCPServerAndClient") 	static TArray ReceiveDataFromTCPServer();  	//"Json","JsonUtilities" 	UFUNCTION(BlueprintCallable,Category = "TCPServerAndClient") 	static void StringToBytes(FString InString,bool& OutBool,TArray& OutBytesArray);  	UFUNCTION(BlueprintCallable,Category = "TCPServerAndClient") 	static void DataTypeToJSON(int32 Int,bool Inbool,FString String,FVector Vector,TArray Array,bool& OutBool,TArray& OutBytesArray);  	UFUNCTION(BlueprintCallable,Category = "TCPServerAndClient") 	static void BytesToString(TArray InBytesArray,FString& OutString); }; 

 客户端.cpp

// 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 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 SendData) { 	if (!Socket) 	{ 		UE_LOG(LogTemp, Log, TEXT("Socket is not connected!")); 		return false; 	}  	// 发送数据部分 	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 AClientActorClass::ReceiveDataFromTCPServer() { 	TArray Bytes;  	if (Socket) 	{ 		uint32 Size; 		while (Socket->HasPendingData(Size)) 		{ 			Bytes.SetNumUninitialized(FMath::Min(Size, 65507u));  			int32 ReadBytes = 0; 			// 读取数据到字节流中 			Socket->Recv(Bytes.GetData(), Bytes.Num(), ReadBytes);  			// 将实际读取的部分截取出来 			Bytes.SetNum(ReadBytes);  			// 如果需要等待接收完整数据再返回,可以设置一个条件,比如接收到特定结束标志 			// 如果已经接收到完整数据,可以直接返回 			return Bytes; 		} 	}  	// 如果没有接收到数据,返回空字节流 	return TArray(); }  void AClientActorClass::StringToBytes(FString InString, bool& OutBool, TArray& 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 Array, 	bool& OutBool, TArray& OutBytesArray) { 	OutBytesArray.Empty(); 	 	TSharedPtr JsonObject = MakeShareable(new FJsonObject);  	JsonObject->SetNumberField("MyInteger",Int); 	JsonObject->SetBoolField("MyBool",Inbool); 	JsonObject->SetStringField("MyString",String);  	TSharedPtr VectorObject = MakeShareable(new FJsonObject); 	JsonObject->SetNumberField("MyVector",Vector.X); 	JsonObject->SetNumberField("MyVector",Vector.Y); 	JsonObject->SetNumberField("MyVector",Vector.Z);  	JsonObject->SetObjectField("MyVector",VectorObject); 	 	TArray> JsonArray; 	for (auto& value : Array) 	{ 		JsonArray.Add(MakeShareable(new FJsonValueNumber(value)));		 	} 	JsonObject->SetArrayField("Array",JsonArray);  	// 将 JSON 对象转换为字符串   	FString OutputString; 	TSharedRef> Writer = TJsonWriterFactory<>::Create(&OutputString); 	if (FJsonSerializer::Serialize(JsonObject.ToSharedRef(), Writer)) 	{ 		Writer->Close();  		// 将字符串转换为字节数组   		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 InBytesArray, FString& OutString) { 	// 检查字节数组是否为空 	if (InBytesArray.Num() == 0) 	{ 		OutString.Empty(); 		GEngine->AddOnScreenDebugMessage(-1, 2.0, FColor::Blue, TEXT("data = null")); 		UE_LOG(LogTemp, Log, TEXT("data = null")); 		return; 	}  	// 将字节流转换为UTF-8字符串 	FString Utf8String = FUTF8ToTCHAR(reinterpret_cast(InBytesArray.GetData()), InBytesArray.Num()).Get();  	// 在这里你可以使用Utf8String进行其他操作,例如将其转换为JSON对象 	// 注意:在UE5中,你可能需要使用FJsonSerializer的Deserialize方法 	TSharedPtr JsonObject; 	TSharedRef> 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字符串赋值给输出参数 	OutString = Utf8String; }  

相关内容

热门资讯

实测分享!微信小程序免费黑科技... 实测分享!微信小程序免费黑科技,蜜瓜大厅辅助免费下载窍门教程(有挂猫腻)1、玩家可以在微信小程序免费...
截至发稿!微乐小程序黑科技,蛮... 截至发稿!微乐小程序黑科技,蛮籽酉阳大贰辅助手册教程(有挂方法)1、进入到微乐小程序黑科技是否有挂之...
一分钟教会你!微信小程序免费黑... 一分钟教会你!微信小程序免费黑科技开挂,欢乐茶馆脚本方案教程(有挂细节)1、微信小程序免费黑科技透视...
热门推荐!微信小程序免费黑科技... 热门推荐!微信小程序免费黑科技辅助,朋友局辅助器绝活教程(发现有挂)热门推荐!微信小程序免费黑科技辅...
2024教程!微信小程序免费黑... 2024教程!微信小程序免费黑科技透视,卡五星辅助器逍遥模块教程(确实有挂)1、玩家可以在微信小程序...
现有关情况通报如下!微信小程序... 现有关情况通报如下!微信小程序免费黑科技开挂,潮汕木虱有辅助挂吗积累教程(有挂详细)1)微信小程序免...
据相关数据显示!微乐小程序黑科... 据相关数据显示!微乐小程序黑科技,途游手游辅助脚本平台教材教程(有挂方略)1、超多福利:超高返利,海...
今日焦点!微信小程序免费黑科技... 今日焦点!微信小程序免费黑科技,途游手游辅助秘籍教程(有挂技巧)1、下载好微信小程序免费黑科技正确养...
最新研发!微乐小程序黑科技,吉... 最新研发!微乐小程序黑科技,吉祥填大坑攻略窍门教程(新版有挂)1、每一步都需要思考,不同水平的挑战微...
三分钟了解!微乐小程序免费黑科... 三分钟了解!微乐小程序免费黑科技,闲逸碰胡辅助积累教程(有挂方法)1、许多玩家不知道微乐小程序免费黑...