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、进入到南宁老友麻将攻略黑...
一分钟了解!雀神辅助器最新款(... 一分钟了解!雀神辅助器最新款(辅助)切实有挂(2022已更新)(哔哩哔哩);1、该软件可以轻松地帮助...
九分钟辅助挂!天天摸摸麻将有挂... 九分钟辅助挂!天天摸摸麻将有挂吗“详细透视辅助挂教程”原来真的有挂1、每一步都需要思考,不同水平的挑...
必备攻略!全民牛牛中心辅助器(... 必备攻略!全民牛牛中心辅助器(辅助挂)外挂透明挂辅助挂(2020已更新)(哔哩哔哩)全民牛牛中心辅助...
八分钟发现!小闲巴渝棋牌有挂吗... 八分钟发现!小闲巴渝棋牌有挂吗,aapoKer都是存在有挂,大神讲解(有挂透视)1、用户打开应用后不...
玩家必看秘籍!边锋老友二打一辅... 玩家必看秘籍!边锋老友二打一辅助(辅助)竟然真的是有挂(2025已更新)(哔哩哔哩);1、下载好边锋...
13钟辅助挂!白金岛跑得快“详... 13钟辅助挂!白金岛跑得快“详细透视辅助神器教程”原来真的有挂1、每一步都需要思考,不同水平的挑战会...
重大科普!聚友互娱手机app辅... 您好,聚友互娱手机app辅助器这款游戏可以开挂的,确实是有挂的,需要了解加微【757446909】很...
五分钟科普!哥哥跑得快有挂吗,... 五分钟科普!哥哥跑得快有挂吗,epoker好像真的有挂,安装教程(有挂揭秘)1、哥哥跑得快有挂吗系统...
盘点十款!六瓣数字消有没有挂(... 盘点十款!六瓣数字消有没有挂(透明挂)确实有挂(2025已更新)(哔哩哔哩);1、玩家可以在六瓣数字...