欧美free性护士vide0shd,老熟女,一区二区三区,久久久久夜夜夜精品国产,久久久久久综合网天天,欧美成人护士h版

目錄

柚子快報(bào)激活碼778899分享:UE4C++UDP通信

柚子快報(bào)激活碼778899分享:UE4C++UDP通信

http://yzkb.51969.com/

UE4C++UDP通信

首先創(chuàng)建繼承自Actor類(lèi)的C++類(lèi),本例中為UdpSend,UdpReceive 具體代碼如下: 首先要在項(xiàng)目的build.cs文件中添加模塊: 添加Sockets,Networking模塊

UdpSend.h

#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 "UdpSend.generated.h"

UCLASS()

class GPSPC_API AUdpSend : public AActor

{

GENERATED_BODY()

public:

// Sets default values for this actor's properties

AUdpSend();

protected:

// Called when the game starts or when spawned

virtual void BeginPlay() override;

virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;

public:

// Called every frame

virtual void Tick(float DeltaTime) override;

FSocket* SenderSocket;

//遠(yuǎn)程的地址

TSharedPtr RemoteAddr;

UFUNCTION(BlueprintCallable, Category = "UDP")

bool StartUDPSender(const FString& YourChosenSocketName, const FString& TheIP, const int32 ThePort, bool UDP);

bool IsUDP;

UFUNCTION(BlueprintCallable, Category = "UDP")

bool RamaUDPSender_SendString(FString ToSend);

UFUNCTION(BlueprintCallable, Category = "UDP")

bool RamaUDPSender_SendDate(TArraydata);

};

UdpSend.cpp

#include "UdpSend.h"

// Sets default values

AUdpSend::AUdpSend()

{

// 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;

SenderSocket = NULL;

}

// Called when the game starts or when spawned

void AUdpSend::BeginPlay()

{

Super::BeginPlay();

}

// Called every frame

void AUdpSend::Tick(float DeltaTime)

{

Super::Tick(DeltaTime);

}

void AUdpSend::EndPlay(const EEndPlayReason::Type EndPlayReason)

{

Super::EndPlay(EndPlayReason);

if (SenderSocket)

{

SenderSocket->Close();

ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->DestroySocket(SenderSocket);

}

}

bool AUdpSend::StartUDPSender(const FString& YourChosenSocketName, const FString& TheIP, const int32 ThePort, bool UDP)

{

RemoteAddr = ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->CreateInternetAddr();

bool bIsValid;

RemoteAddr->SetIp(*TheIP, bIsValid);

RemoteAddr->SetPort(ThePort);

if (!bIsValid)

{

UE_LOG(LogTemp, Warning, TEXT("Rama UDP Sender>> IP address was not valid! "), *TheIP);

return false;

}

SenderSocket = FUdpSocketBuilder(*YourChosenSocketName)

.AsReusable()

.WithBroadcast() // 廣播

.WithSendBufferSize(2 * 1024 * 1024);

int32 SendSize = 2 * 1024 * 1024;

SenderSocket->SetSendBufferSize(SendSize, SendSize);

SenderSocket->SetReceiveBufferSize(SendSize, SendSize);

if (bIsValid)

{

bIsValid = true;

}

return bIsValid;

}

bool AUdpSend::RamaUDPSender_SendString(FString ToSend)//發(fā)送消息

{

if (!SenderSocket)

{

UE_LOG(LogTemp, Warning, TEXT("No sender socket"));

return false;

}

//消息處理

int32 BytesSent = 0;

FString serialized = ToSend;

TCHAR* serializedChar = serialized.GetCharArray().GetData();

int32 size = FCString::Strlen(serializedChar);

int32 sent = 0;

SenderSocket->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("UDP Send Succcess! INFO Sent = %s "), *ToSend);

return true;

}

bool AUdpSend::RamaUDPSender_SendDate(TArray data)

{

if (!SenderSocket)

{

UE_LOG(LogTemp, Warning, TEXT("No sender socket"));

return false;

}

//消息處理

int32 BytesSent = 0;

int32 size = data.Num();

int32 sent = 0;

SenderSocket->SendTo(&data[0], 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("UDP Send Succcess! INFO Sent = %s "), *ToSend);

return true;

}

其中RamaUDPSender_SendString(FString ToSend);函數(shù)用來(lái)發(fā)送字符串,RamaUDPSender_SendDate用于發(fā)送字節(jié)數(shù)據(jù)

UdpReceive.h

#include "CoreMinimal.h"

#include "GameFramework/Actor.h"

#include "Runtime/Sockets/Public/Sockets.h"

#include "Sockets/Public/SocketSubsystem.h"

#include"Runtime/Networking/Public/Common/UdpSocketReceiver.h"

#include "Runtime/Networking/Public/Common/UdpSocketBuilder.h"

#include "Networking/Public/Interfaces/IPv4/IPv4Address.h"

#include "UdpReceive.generated.h"

DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FOnUdpByteMessageDelegate, const TArray&, Message, const FString&, SenderIp);

UCLASS()

class GPSPC_API AUdpReceive : public AActor

{

GENERATED_BODY()

public:

// Sets default values for this actor's properties

AUdpReceive();

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 EndPlayReason) override;

FSocket* ListenSocket;

FUdpSocketReceiver* Receiver = nullptr;

//FUdpSocketReceiver* UDPReceiver = nullptr;

public:

UFUNCTION(BlueprintCallable, Category = "UDP")

void StartUDPReceiver(const FString& YourChosenSocketName, const FString& TheIP, const int32 ThePort, bool& success);

UFUNCTION(BlueprintCallable, Category = "UDP")

void DataRecv(FString& str, bool& success);

UFUNCTION(BlueprintCallable, Category = "UDP")

TArray DataRecvBytes(bool& success);

UPROPERTY(BlueprintAssignable, Category = "Socket|Event")

FOnUdpByteMessageDelegate OnByteMessage;

};

UdpReceive.cpp

#include "UdpReceive.h"

// Sets default values

AUdpReceive::AUdpReceive()

{

// 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 AUdpReceive::BeginPlay()

{

Super::BeginPlay();

}

// Called every frame

void AUdpReceive::Tick(float DeltaTime)

{

Super::Tick(DeltaTime);

}

void AUdpReceive::EndPlay(const EEndPlayReason::Type EndPlayReason)

{

Super::EndPlay(EndPlayReason);

//delete UDPReceiver;

//UDPReceiver = nullptr;

//Clear all sockets!

// makes sure repeat plays in Editor dont hold on to old sockets!

if (this->Receiver != nullptr)

{

this->Receiver->Stop();

delete this->Receiver;

this->Receiver = nullptr;

}

if (ListenSocket)

{

ListenSocket->Close();

ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->DestroySocket(ListenSocket);

}

}

void AUdpReceive::StartUDPReceiver(const FString& YourChosenSocketName, const FString& TheIP, const int32 ThePort, bool& success)

{

TSharedRef targetAddr = ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->CreateInternetAddr();

FIPv4Address Addr;

FIPv4Address::Parse(TheIP, Addr);

FIPv4Endpoint Endpoint(FIPv4Address::Any, ThePort); //所有ip地址本地

//FIPv4Endpoint Endpoint(Addr, ThePort); //指定ip地址

ListenSocket = FUdpSocketBuilder(*YourChosenSocketName)

.AsNonBlocking()

.AsReusable()

.BoundToEndpoint(Endpoint)

.WithReceiveBufferSize(2 * 1024 * 1024);

//BUFFER SIZE

int32 BufferSize = 2 * 1024 * 1024;

ListenSocket->SetSendBufferSize(BufferSize, BufferSize);

ListenSocket->SetReceiveBufferSize(BufferSize, BufferSize);

if (!ListenSocket)

{

UE_LOG(LogTemp, Warning, TEXT("No Scokets"));

success = false;

}

if (ListenSocket)

{

UE_LOG(LogTemp, Warning, TEXT("The receiver is initialized"));

success = true;

this->Receiver = new FUdpSocketReceiver(ListenSocket, FTimespan::FromMilliseconds(100), TEXT("DEFAULT"));

this->Receiver->OnDataReceived().BindLambda([this](const FArrayReaderPtr& Data, const FIPv4Endpoint& From)

{

TArray ReceiveBytes;

ReceiveBytes.Append(Data->GetData(), Data->Num());

FMemory::Memcpy(ReceiveBytes.GetData(), Data->GetData(), Data->Num() * sizeof(uint8));

if (this->OnByteMessage.IsBound())

{

this->OnByteMessage.Broadcast(ReceiveBytes, From.ToString());

}

});

//this->Receiver->OnDataReceived().BindUFunction(this, "DataRecvBytes2" );

this->Receiver->Start();

}

}

void AUdpReceive::DataRecv(FString& str, bool& success)

{

if (!ListenSocket)

{

UE_LOG(LogTemp, Warning, TEXT("No Send Sockets"));

success = false;

//return success;

}

TSharedRef targetAddr = ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->CreateInternetAddr();

TArray ReceivedData;//定義一個(gè)接收器

uint32 Size;

if (ListenSocket->HasPendingData(Size))

{

success = true;

str = "";

uint8* Recv = new uint8[Size];

int32 BytesRead = 0;

ReceivedData.SetNumUninitialized(FMath::Min(Size, 65507u));

ListenSocket->RecvFrom(ReceivedData.GetData(), ReceivedData.Num(), BytesRead, *targetAddr);//創(chuàng)建遠(yuǎn)程接收地址

char ansiiData[1024];

memcpy(ansiiData, ReceivedData.GetData(), BytesRead);//拷貝數(shù)據(jù)到接收器

ansiiData[BytesRead] = 0; //判斷數(shù)據(jù)結(jié)束

FString debugData = ANSI_TO_TCHAR(ansiiData); //字符串轉(zhuǎn)換

str = debugData;

// memset(ansiiData,0,1024);//清空

}

else

{

success = false;

}

}

TArray AUdpReceive::DataRecvBytes(bool& success)

{

if (!ListenSocket)

{

UE_LOG(LogTemp, Warning, TEXT("No Send Sockets"));

success = false;

//return success;

}

TSharedRef targetAddr = ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->CreateInternetAddr();

TArray ReceivedData;//定義一個(gè)接收器

uint32 Size;

if (ListenSocket->HasPendingData(Size))

{

success = true;

uint8* Recv = new uint8[Size];

int32 BytesRead = 0;

ReceivedData.SetNumUninitialized(FMath::Min(Size, 65507u));

ListenSocket->RecvFrom(ReceivedData.GetData(), ReceivedData.Num(), BytesRead, *targetAddr);//創(chuàng)建遠(yuǎn)程接收地址

// memset(ansiiData,0,1024);//清空

ReceivedData.SetNum(BytesRead);

return ReceivedData;

}

else

{

success = false;

}

return TArray();

}

關(guān)于Udp的接收,可以使用線程與非線程的方式。在代碼中主要就是是否使用FUdpSocketReceiver* Receiver 這個(gè)變量??梢钥吹皆赟tartUDPReceiver函數(shù)中this->Receiver->Start();該語(yǔ)句的作用就是開(kāi)辟一個(gè)線程用于監(jiān)聽(tīng)Udp數(shù)據(jù),具體實(shí)現(xiàn)已經(jīng)由UE4底層封裝好,不必深究。如果不打算使用線程,則直接使用DataRecv或者DataRecvBytes函數(shù)。 代碼編譯完后,生成對(duì)應(yīng)的藍(lán)圖子類(lèi)。 對(duì)于MyUdpSend: 開(kāi)始運(yùn)行的時(shí)候用StartUDPSender初始化,接著調(diào)用sendData傳輸數(shù)據(jù)。 對(duì)于MyUdpReceiver: 如果使用線程,則參照上圖,調(diào)用start函數(shù),然后創(chuàng)建事件綁定,當(dāng)接收到數(shù)據(jù)時(shí)便會(huì)觸發(fā)事件。 如果不適用線程,則將代碼中的StartUDPReceiver函數(shù)內(nèi)

this->Receiver = new FUdpSocketReceiver(ListenSocket, FTimespan::FromMilliseconds(100), TEXT("DEFAULT"));

this->Receiver->OnDataReceived().BindLambda([this](const FArrayReaderPtr& Data, const FIPv4Endpoint& From)

{

TArray ReceiveBytes;

ReceiveBytes.Append(Data->GetData(), Data->Num());

FMemory::Memcpy(ReceiveBytes.GetData(), Data->GetData(), Data->Num() * sizeof(uint8));

if (this->OnByteMessage.IsBound())

{

this->OnByteMessage.Broadcast(ReceiveBytes, From.ToString());

}

});

//this->Receiver->OnDataReceived().BindUFunction(this, "DataRecvBytes2" );

this->Receiver->Start();

這部分注釋掉,然后藍(lán)圖中如下: 區(qū)別在于,由于不是線程,所以datarecv函數(shù)是單次觸發(fā),即調(diào)用一次,就檢查有沒(méi)有接收到數(shù)據(jù),因此需要放到tick事件中。

注:

如果采用線程進(jìn)行數(shù)據(jù)接收的監(jiān)聽(tīng),則需注意,線程中不能調(diào)用刪除actor,object的相關(guān)事件,因?yàn)閷?duì)于線程而言,多線程通信進(jìn)行修改操作會(huì)導(dǎo)致線程奔潰的。這部分的相關(guān)內(nèi)容可以搜索UE4多線程相關(guān)的知識(shí)。 之前找過(guò)一些問(wèn)答可以參考一下: 也參考了另一個(gè)博主的博客: 自己創(chuàng)建的線程哪些不能做?官方文檔上的回答:

https://wiki.unrealengine.com/Multi-Threading:_How_to_Create_Threads_in_UE4#What_Not_to_Do

Do not try to modify, create, or delete UObjects from other threads! You can prepare all the data / do all the calculations, but only the game thread should be actually spawning / modifying / deleting UObjects / AActors.

Dont try to use TimerManager outside of the game thread ? Don’t try to draw debug lines/points etc, as it will likely crash, ie DrawDebugLine(etc…)

柚子快報(bào)激活碼778899分享:UE4C++UDP通信

http://yzkb.51969.com/

好文鏈接

評(píng)論可見(jiàn),查看隱藏內(nèi)容

本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點(diǎn)和立場(chǎng)。

轉(zhuǎn)載請(qǐng)注明,如有侵權(quán),聯(lián)系刪除。

本文鏈接:http://m.gantiao.com.cn/post/19014570.html

發(fā)布評(píng)論

您暫未設(shè)置收款碼

請(qǐng)?jiān)谥黝}配置——文章設(shè)置里上傳

掃描二維碼手機(jī)訪問(wèn)

文章目錄