在配置文件加上Networking。
使用socket加以上头文件
通过传过来的IP与端口号进行一个绑定,第一行就是将BindIP分割然后分别放进ip的四个值内(A,B,C,D),然后创建一个FInternetAddr类型的智能指针,将ip的值与外界传来的端口号对FInternetAddr进行一个初始化赋值,最后对让socket对地址进行一个绑定。
服务器进行一个监听,看客户端是否发出消息让服务器进行接收
对消息进行接收
客户端发送消息,先将要发送的字符串进行char的转化。
然后对处理后的数据发送到指定地址
FSocket::HasPendingData将返回一个值,通知您是否
从套接字读取是安全的。
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "Networking/Public/Interfaces/IPv4/IPv4Address.h"
#include "ServerSocket.generated.h"
UCLASS()
class MYCTEST_API AServerSocket : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
AServerSocket();
FSocket* ServerSocket;
FSocket* ClientSocket;
FTimerHandle SocketTimerHandle;
FIPv4Address ip;
FVector currentLoc;
float SocketDelta;
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
virtual void EndPlay(const EEndPlayReason::Type EEndPlayReason);
bool CreateSocket();
//Bind创建的Socket 需要ip和port
bool BindSocket(const FString& BindIP, const int32 BindPort);
//监听Socket
bool ListenSocket(int32 MaxConnectionNum);
//Accept Client
bool AcceptSocket();
//收发消息
bool sendMsg(const FString& Msg);
FString RecvMsg();
//转换函数
FString StringFromBinaryArray(const TArray& BinaryArray) {
return FString(ANSI_TO_TCHAR(reinterpret_cast(BinaryArray.GetData())));
}
UFUNCTION(BlueprintCallable)
void Test(const FString &BindIP, const int32 Port, const int32 MaxListener);
void HandleFunc();
};
// Fill out your copyright notice in the Description page of Project Settings.
#include "ServerSocket.h"
#include "SocketSubsystem.h"
#include "Sockets.h"
#include "Engine/World.h"
#include "TimerManager.h"
#include "Kismet/KismetStringLibrary.h"
#include "UObject/ConstructorHelpers.h"
#include "Components/StaticMeshComponent.h"
#include "Engine/StaticMesh.h"
// Sets default values
// Called when the game starts or when spawned
#define SPHERE_PATH TEXT("/Game/StarterContent/Shapes/Shape_Sphere")
AServerSocket::AServerSocket()
{
// 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;
currentLoc = FVector(0.f, 0.f, 0.f);
UStaticMeshComponent* staticMeshComponent = CreateDefaultSubobject(TEXT("Mesh"));
struct FContructor {
ConstructorHelpers::FObjectFinderOptional Mesh;
FContructor() : Mesh(SPHERE_PATH) {}
};
static FContructor ConstructorStatics;
auto tempMesh = ConstructorStatics.Mesh;
staticMeshComponent->SetupAttachment(RootComponent);
if (tempMesh.Succeeded()) {
staticMeshComponent->SetStaticMesh(tempMesh.Get());
}
}
// Called when the game starts or when spawned
void AServerSocket::BeginPlay()
{
Super::BeginPlay();
#if 0
APlayerController* myPlayerController = UGameplayStatics::GetPlayerController(this, 0);
if (myPlayerController) {
this->EnableInput(myPlayerController);
}
#endif
}
// Called every frame
void AServerSocket::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
SocketDelta = DeltaTime;
AddActorWorldOffset(currentLoc);
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Yellow, FString::Printf(TEXT("%d-%d-%d"), currentLoc.X, currentLoc.Y, currentLoc.Z));
}
void AServerSocket::EndPlay(const EEndPlayReason::Type EndPlayReason)
{
Super::EndPlay(EndPlayReason);
if (ServerSocket) {
ServerSocket->Close();
ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->DestroySocket(ServerSocket);
}
if (ClientSocket) {
ClientSocket->Close();
ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->DestroySocket(ClientSocket);
}
}
bool AServerSocket::CreateSocket()
{
ServerSocket = ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->CreateSocket(NAME_Stream, "Send Information", false);
if (!ServerSocket) {
return false;
}
return true;
}
bool AServerSocket::BindSocket(const FString& BindIP, const int32 BindPort)
{
FIPv4Address::Parse(BindIP, ip);
TSharedPtr addr = ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->CreateInternetAddr();
addr->SetIp(ip.Value);
addr->SetPort(BindPort);
bool bBind = ServerSocket->Bind(*addr);
return bBind;
}
bool AServerSocket::ListenSocket(int32 MaxConnectionNum)
{
ServerSocket->Listen(MaxConnectionNum);
return false;
}
bool AServerSocket::AcceptSocket()
{
ClientSocket = ServerSocket->Accept("Send Information");
if (!ClientSocket) return false;
return true;
}
bool AServerSocket::sendMsg(const FString& Msg)
{
TSharedPtr addr = ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->CreateInternetAddr();
FText outputSample = FText::FromString(addr->ToString(false));
GEngine->AddOnScreenDebugMessage(-1, 100.f, FColor::Yellow, addr->ToString(true));
FString tempMsg = Msg;
TCHAR* MsgChar = tempMsg.GetCharArray().GetData();
int32 size = FCString::Strlen(MsgChar) + 1;
int sent = 0;
bool bSend;
if (ClientSocket) {
bSend = ClientSocket->SendTo((uint8*)TCHAR_TO_UTF8(MsgChar), size, sent, *addr);
}
bSend ? GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Green, TEXT("Socket Sent Success")) : GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, TEXT("Socket Failed"));
return bSend;
}
FString AServerSocket::RecvMsg()
{
TSharedPtr addr = ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->CreateInternetAddr();
TArray ReceiveData;
FString ReceivedUE4String = "";
uint32 Size;
if (ClientSocket->HasPendingData(Size)) {
uint8* Recv = new uint8[Size];
ReceiveData.SetNumUninitialized(FMath::Min(Size, 65507u));
int32 ByteRead = 0;
ClientSocket->RecvFrom(ReceiveData.GetData(), ReceiveData.Num(), ByteRead, *addr);
if (ReceiveData.Num() > 0) {
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Green, FString::Printf(TEXT("Data Bytes Read-> %d"), ReceiveData.Num()));
ReceivedUE4String = StringFromBinaryArray(ReceiveData);
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Green, FString::Printf(TEXT("Data String Read-> %d"), ReceiveData.Num()));
}
else {
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Green, FString::Printf(TEXT("Data Byte Read Failed"), ReceiveData.Num()));
}
return ReceivedUE4String;
}
return ReceivedUE4String;
}
void AServerSocket::Test(const FString& BindIP, const int32 Port, const int32 MaxListener) {
if (CreateSocket()) {
if (BindSocket(BindIP, Port)) {
if (ListenSocket(MaxListener)) {
if (AcceptSocket()) {
UWorld* world = GetWorld();
world->GetTimerManager().SetTimer(SocketTimerHandle, this, &AServerSocket::HandleFunc, SocketDelta, true);
}
}
}
}
}
void AServerSocket::HandleFunc()
{
bool outIsValid = false;
UKismetStringLibrary::Conv_StringToVector(RecvMsg(), currentLoc, outIsValid);
}