UE4修改自Rama的UDP通信蓝图插件
UE4.15没有提供蓝图UDP的组件,可以在网上找到一个ID叫Rama写的源代码,我把它封装成插件了(MyUdpPlugin),方便在各个UE4版本工程中使用UDP通信。
使用方式:
1、在自己的工程根目录下新建一个Plugins文件夹,将MyUdpPlugin拷贝进去
2、一般情况下需要重新编译一下插件,最终你会得到一个插件的dll

3、新建一个蓝图类。接收UDP信息就选择MyUDPReceiver,发送UDP就选择MyUDPSender,这两个类都继承自Actor

4、将新建的蓝图类拖拽一个实例到关卡蓝图中

5、编辑蓝图。可以使用网络调试助手调试通信是否成功。
关于ListenPort,RemotePort和RemoteIP,如果在工程打包以后想改变,可以手动添加配置文件,在配置文件中修改



以下是插件源代码

MyUdpPlugin.uplugin
{
"FileVersion": ,
"Version": ,
"VersionName": "1.0",
"FriendlyName": "MyUdpPlugin",
"Description": "",
"Category": "Other",
"CreatedBy": "",
"CreatedByURL": "",
"DocsURL": "",
"MarketplaceURL": "",
"SupportURL": "",
"CanContainContent": true,
"IsBetaVersion": false,
"Installed": false,
"Modules": [
{
"Name": "MyUdpPlugin",
"Type": "Runtime",
"LoadingPhase": "PreLoadingScreen"
}
]
}
MyUdpPlugin.Build.cs
// Some copyright should be here... using UnrealBuildTool; public class MyUdpPlugin : ModuleRules
{
public MyUdpPlugin(TargetInfo Target)
{ PublicIncludePaths.AddRange(
new string[] {
"MyUdpPlugin/Public" // ... add public include paths required here ...
}
); PrivateIncludePaths.AddRange(
new string[] {
"MyUdpPlugin/Private", // ... add other private include paths required here ...
}
); PublicDependencyModuleNames.AddRange(
new string[]
{
"Core",
// ... add other public dependencies that you statically link with here ...
}
); PrivateDependencyModuleNames.AddRange(
new string[]
{
"CoreUObject",
"Engine",
"Slate",
"SlateCore",
"Sockets", "Networking"
// ... add private dependencies that you statically link with here ...
}
); DynamicallyLoadedModuleNames.AddRange(
new string[]
{
// ... add any modules that your module loads dynamically here ...
}
);
}
}
MyUdpPlugin.h
// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved. #pragma once #include "ModuleManager.h" class FMyUdpPluginModule : public IModuleInterface
{
public: /** IModuleInterface implementation */
virtual void StartupModule() override;
virtual void ShutdownModule() override;
};
MyUdpPlugin.cpp
// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved. #include "MyUdpPlugin.h" #define LOCTEXT_NAMESPACE "FMyUdpPluginModule" void FMyUdpPluginModule::StartupModule()
{
// This code will execute after your module is loaded into memory; the exact timing is specified in the .uplugin file per-module } void FMyUdpPluginModule::ShutdownModule()
{
// This function may be called during shutdown to clean up your module. For modules that support dynamic reloading,
// we call this function before unloading the module. } #undef LOCTEXT_NAMESPACE IMPLEMENT_MODULE(FMyUdpPluginModule, MyUdpPlugin)
MyUDPReceiver.h
// Fill out your copyright notice in the Description page of Project Settings. #pragma once #include "Networking.h"
//#include "AnyCustomData.h"//如果发送、接收方都是UE4,可以使用FArchive对传输数据进行序列化与反序列化
#include "GameFramework/Actor.h"
#include "Engine.h"
#include "MyUDPReceiver.generated.h" UCLASS()
class AMyUDPReceiver : public AActor
{
GENERATED_BODY() public:
// Sets default values for this actor's properties
AMyUDPReceiver(); protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override; public:
// Called every frame
virtual void Tick(float DeltaTime) override; /** Data has been received!! */
UFUNCTION(BlueprintImplementableEvent, Category = "MyUDPSender")
void DataReceived(const TArray<uint8>& rawData, const FString& tryToString); FSocket* ListenSocket; FUdpSocketReceiver* UDPReceiver = nullptr;
void Recv(const FArrayReaderPtr& ArrayReaderPtr, const FIPv4Endpoint& EndPt); /*
* Trying read ListenPort parameter from GameIni config, if ListenPort!=0,
* the parameter ListenPort will be overridden.
* You can config them in YourProject\Config\DefaultGame.ini or
* YourPackagedProject\Saved\Config\WindowsNoEditor\Game.ini.
* [MyUDP]
* ListenPort=2016
*/
UFUNCTION(BlueprintCallable, Category = "MyUDPSender")
bool StartUDPReceiver(const FString& YourChosenSocketName, int32 ListenPort = ); UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "MyUDPSender")
bool ShowOnScreenDebugMessages; //ScreenMsg
FORCEINLINE void ScreenMsg(const FString& Msg)
{
if (!ShowOnScreenDebugMessages) return;
GEngine->AddOnScreenDebugMessage(-, .f, FColor::Red, *Msg);
}
FORCEINLINE void ScreenMsg(const FString& Msg, const int32 Value)
{
if (!ShowOnScreenDebugMessages) return;
GEngine->AddOnScreenDebugMessage(-, .f, FColor::Red, FString::Printf(TEXT("%s %d"), *Msg, Value));
}
FORCEINLINE void ScreenMsg(const FString& Msg, const int32 Value, const FString& Msg2)
{
if (!ShowOnScreenDebugMessages) return;
GEngine->AddOnScreenDebugMessage(-, .f, FColor::Red, FString::Printf(TEXT("%s %d %s"), *Msg, Value, *Msg2));
}
/** Called whenever this actor is being removed from a level */
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
};
MyUDPReceiver.cpp
#include "MyUdpPlugin.h" #include "MyUDPReceiver.h"
#include <string> // Sets default values
AMyUDPReceiver::AMyUDPReceiver()
{
// 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; ListenSocket = NULL;
ShowOnScreenDebugMessages = true;
} // Called when the game starts or when spawned
void AMyUDPReceiver::BeginPlay()
{
Super::BeginPlay(); } // Called every frame
void AMyUDPReceiver::Tick(float DeltaTime)
{
Super::Tick(DeltaTime); } void AMyUDPReceiver::EndPlay(const EEndPlayReason::Type EndPlayReason)
{
Super::EndPlay(EndPlayReason); delete UDPReceiver;
UDPReceiver = nullptr; //Clear all sockets!
//makes sure repeat plays in Editor don't hold on to old sockets!
if (ListenSocket)
{
ListenSocket->Close();
ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->DestroySocket(ListenSocket);
}
} //Start UDP Receiver
bool AMyUDPReceiver::StartUDPReceiver(const FString& YourChosenSocketName, int32 ListenPort)
{
int32 listenPortFromGameIni = ;
GConfig->GetInt(TEXT("MyUDP"), TEXT("ListenPort"), listenPortFromGameIni, GGameIni);
//ScreenMsg(GGameIni);
ScreenMsg("ListenPort From Game.ini: [MyUDP] ListenPort=", listenPortFromGameIni);
if (listenPortFromGameIni!=)
{
ListenPort = listenPortFromGameIni;
} //Create Socket
FIPv4Endpoint Endpoint(FIPv4Address::Any, ListenPort); //BUFFER SIZE
int32 BufferSize = * * ; ListenSocket = FUdpSocketBuilder(*YourChosenSocketName)
.AsNonBlocking()
.AsReusable()
.BoundToEndpoint(Endpoint)
.WithReceiveBufferSize(BufferSize);
; FTimespan ThreadWaitTime = FTimespan::FromMilliseconds();
UDPReceiver = new FUdpSocketReceiver(ListenSocket, ThreadWaitTime, TEXT("UDP RECEIVER"));
UDPReceiver->OnDataReceived().BindUObject(this, &AMyUDPReceiver::Recv); UDPReceiver->Start(); ScreenMsg("UDP Receiver Initialized Successfully!!!");
return true;
} void AMyUDPReceiver::Recv(const FArrayReaderPtr& ArrayReaderPtr, const FIPv4Endpoint& EndPt)
{
//FAnyCustomData Data;
//*ArrayReaderPtr << Data; //Now de-serializing! See AnyCustomData.h
//BPEvent_DataReceived(Data); //BP Event int32 dataByteNum = ArrayReaderPtr->Num();
TArray<uint8> ReceivedData;
for (int i = ; i < dataByteNum; i++)
{
uint8 tmp;
*ArrayReaderPtr << tmp;
ReceivedData.Add(tmp);
}
ReceivedData.Add('\0');
FString tryToString(reinterpret_cast<const char*>(ReceivedData.GetData()));
ReceivedData.RemoveSingle('\0');
ScreenMsg("Received from " + EndPt.ToString() + ", Received bytes = ", dataByteNum, ", Received String =" + tryToString);
DataReceived(ReceivedData, tryToString);
}
MyUDPSender.h
// Fill out your copyright notice in the Description page of Project Settings. #pragma once #include "Networking.h"
#include "GameFramework/Actor.h"
#include "MyUDPSender.generated.h" UCLASS()
class AMyUDPSender : public AActor
{
GENERATED_BODY() public:
// Sets default values for this actor's properties
AMyUDPSender(); protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override; public:
// Called every frame
virtual void Tick(float DeltaTime) override; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "MyUDPSender")
bool ShowOnScreenDebugMessages; TSharedPtr<FInternetAddr> RemoteAddr;
FSocket* SenderSocket; UFUNCTION(BlueprintCallable, Category = "MyUDPSender")
bool SendString(FString ToSend); /*
* Trying read parameters from GameIni config, if RemoteIP!="" or RemotePort!=0,
* the two parameters(RemoteIP and RemotePort) will be overridden.
* You can config them in YourProject\Config\DefaultGame.ini or
* YourPackagedProject\Saved\Config\WindowsNoEditor\Game.ini.
* [MyUDP]
* RemoteIP=192.168.1.117
* RemoterPort=2016
*/
UFUNCTION(BlueprintCallable, Category = "MyUDPSender")
bool StartUDPSender(const FString& YourChosenSocketName,
FString RemoteIP="127.0.0.1",int32 RemotePort=); //ScreenMsg
FORCEINLINE void ScreenMsg(const FString& Msg)
{
if (!ShowOnScreenDebugMessages) return;
GEngine->AddOnScreenDebugMessage(-, .f, FColor::Red, *Msg);
}
FORCEINLINE void ScreenMsg(const FString& Msg, const int32 Value)
{
if (!ShowOnScreenDebugMessages) return;
GEngine->AddOnScreenDebugMessage(-, .f, FColor::Red, FString::Printf(TEXT("%s %d"), *Msg, Value));
}
FORCEINLINE void ScreenMsg(const FString& Msg, const int32 Value, const FString& Msg2)
{
if (!ShowOnScreenDebugMessages) return;
GEngine->AddOnScreenDebugMessage(-, .f, FColor::Red, FString::Printf(TEXT("%s %d %s"), *Msg, Value, *Msg2));
} /** Called whenever this actor is being removed from a level */
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
};
MyUDPSender.cpp
#include "MyUdpPlugin.h" //#include "AnyCustomData.h"//如果发送、接收方都是UE4,可以使用FArchive对传输数据进行序列化与反序列化
#include "MyUDPSender.h"
#include <string>
#include "StringConv.h" // Sets default values
AMyUDPSender::AMyUDPSender()
{
// 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;
ShowOnScreenDebugMessages = true;
} // Called when the game starts or when spawned
void AMyUDPSender::BeginPlay()
{
Super::BeginPlay(); } // Called every frame
void AMyUDPSender::Tick(float DeltaTime)
{
Super::Tick(DeltaTime); } void AMyUDPSender::EndPlay(const EEndPlayReason::Type EndPlayReason)
{
Super::EndPlay(EndPlayReason); if (SenderSocket)
{
SenderSocket->Close();
ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->DestroySocket(SenderSocket);
}
} bool AMyUDPSender::StartUDPSender(
const FString& YourChosenSocketName,
FString RemoteIP /*= "127.0.0.1"*/, int32 RemotePort /*= 2017*/
)
{
FString remoteIPFromGameIni = TEXT("");
int32 remotePortFromGameIni = ;
GConfig->GetString(TEXT("MyUDP"), TEXT("RemoteIP"), remoteIPFromGameIni, GGameIni);
GConfig->GetInt(TEXT("MyUDP"), TEXT("RemotePort"), remotePortFromGameIni, GGameIni);
//ScreenMsg(GGameIni);
ScreenMsg("RemoteAddress From Game.ini: [MyUDP] RemoteIP="+ remoteIPFromGameIni +", RemotePort=", remotePortFromGameIni);
if (!remoteIPFromGameIni.IsEmpty())
{
RemoteIP = remoteIPFromGameIni;
}
if (remotePortFromGameIni!=)
{
RemotePort = remotePortFromGameIni;
} //Create Remote Address.
RemoteAddr = ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->CreateInternetAddr(); bool bIsValid;
RemoteAddr->SetIp(*RemoteIP, bIsValid);
RemoteAddr->SetPort(RemotePort); if (!bIsValid)
{
ScreenMsg("IP address was not valid!" + RemoteIP);
return false;
} SenderSocket = FUdpSocketBuilder(*YourChosenSocketName)
.AsReusable()
.WithBroadcast()
; //check(SenderSocket->GetSocketType() == SOCKTYPE_Datagram); //Set Send Buffer Size
int32 SendSize = * * ;
SenderSocket->SetSendBufferSize(SendSize, SendSize);
SenderSocket->SetReceiveBufferSize(SendSize, SendSize); ScreenMsg("UDP Sender Initialized Successfully!!!");
return true;
} bool AMyUDPSender::SendString(FString ToSend)
{
if (!SenderSocket)
{
ScreenMsg("No sender socket");
return false;
} int32 BytesSent = ; //FAnyCustomData NewData;
//NewData.Scale = FMath::FRandRange(0, 1000);
//NewData.Count = FMath::RandRange(0, 100);
//NewData.Color = FLinearColor(FMath::FRandRange(0, 1), FMath::FRandRange(0, 1), FMath::FRandRange(0, 1), 1);
//FArrayWriter Writer;
//Writer << NewData; //Serializing our custom data, thank you UE4!
//SenderSocket->SendTo(Writer.GetData(), Writer.Num(), BytesSent, *RemoteAddr); TCHAR* pSendData = ToSend.GetCharArray().GetData();
int32 nDataLen = FCString::Strlen(pSendData);
uint8* dst = (uint8*)TCHAR_TO_UTF8(pSendData);
SenderSocket->SendTo(dst, nDataLen, BytesSent, *RemoteAddr); if (BytesSent <= )
{
const FString Str = "Socket is valid but the sender sent 0 bytes!";
UE_LOG(LogTemp, Error, TEXT("%s"), *Str);
ScreenMsg(Str);
return false;
} ScreenMsg("UDP Send Success! Bytes Sent = ", BytesSent, ", ToSend String =" + ToSend+", To "+ RemoteAddr->ToString(true)); return true;
}
AnyCustomData.h
// Fill out your copyright notice in the Description page of Project Settings. #pragma once
#include "AnyCustomData.generated.h" USTRUCT(BlueprintType)
struct FAnyCustomData
{
GENERATED_USTRUCT_BODY() UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Joy Color")
FString Name = "Victory!"; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Joy Color")
int32 Count = ; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Joy Color")
float Scale = .f; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Joy Color")
FLinearColor Color = FLinearColor::Red; FAnyCustomData() {};
~FAnyCustomData() {};
};
FORCEINLINE FArchive& operator<<(FArchive &Ar, FAnyCustomData& TheStruct)
{
Ar << TheStruct.Name;
Ar << TheStruct.Count;
Ar << TheStruct.Scale;
Ar << TheStruct.Color; return Ar;
}
UE4修改自Rama的UDP通信蓝图插件的更多相关文章
- 高性能 TCP & UDP 通信框架 HP-Socket v3.3.1
HP-Socket 是一套通用的高性能 TCP/UDP 通信框架,包含服务端组件.客户端组件和 Agent 组件,广泛适用于各种不同应用场景的 TCP/UDP 通信系统,提供 C/C++.C#.Del ...
- 高性能 TCP & UDP 通信框架 HP-Socket v3.2.3
HP-Socket 是一套通用的高性能 TCP/UDP 通信框架,包含服务端组件.客户端组件和 Agent 组件,广泛适用于各种不同应用场景的 TCP/UDP 通信系统,提供 C/C++.C#.Del ...
- 高性能 TCP & UDP 通信框架 HP-Socket v3.2.2 正式发布
HP-Socket 是一套通用的高性能 TCP/UDP 通信框架,包含服务端组件.客户端组件和 Agent 组件,广泛适用于各种不同应用场景的 TCP/UDP 通信系统,提供 C/C++.C#.Del ...
- QT之UDP通信
前言:前一篇讲了TCP通信,这篇来看看UDP通信. 这里说明一下,UDP通信中分为三种通信分别为单播.组播和广播,下面将一一为大家介绍. 同样的我们都需要在工程文件中添加network QT += c ...
- 【RL-TCPnet网络教程】第17章 RL-TCPnet之UDP通信
第17章 RL-TCPnet之UDP通信 本章节为大家讲解RL-TCPnet的UDP通信实现,学习本章节前,务必要优先学习第16章UDP用户数据报协议基础知识.有了这些基础知识之后,再搞本章 ...
- Java入门网络编程-使用UDP通信
程序说明: 以下代码,利用java的网络编程,使用UDP通信作为通信协议,描述了一个简易的多人聊天程序,此程序可以使用公网或者是局域网进行聊天,要求有一台服务器.程序一共分为2个包,第一个包:udp, ...
- 高性能 TCP & UDP 通信框架 HP-Socket v3.5.3
HP-Socket 是一套通用的高性能 TCP/UDP 通信框架,包含服务端组件.客户端组件和 Agent 组件,广泛适用于各种不同应用场景的 TCP/UDP 通信系统,提供 C/C++.C#.Del ...
- 高性能 TCP & UDP 通信框架 HP-Socket v3.5.2
HP-Socket 是一套通用的高性能 TCP/UDP 通信框架,包含服务端组件.客户端组件和 Agent 组件,广泛适用于各种不同应用场景的 TCP/UDP 通信系统,提供 C/C++.C#.Del ...
- 高性能 TCP & UDP 通信框架 HP-Socket v3.5.1
HP-Socket 是一套通用的高性能 TCP/UDP 通信框架,包含服务端组件.客户端组件和 Agent 组件,广泛适用于各种不同应用场景的 TCP/UDP 通信系统,提供 C/C++.C#.Del ...
随机推荐
- ubuntu怎用使用命令搜索软件源中的软件
转自:http://jingyan.baidu.com/article/6d704a13f6bf1b28da51ca69.html ubuntu中是用apt-get来进行软件安装的,我们首先打开终端来 ...
- 使用寄存器点亮LED——前言基础知识
在点亮LED之前,我们需要具备一些基础知识: GPIO—general purpose intput output 是通用输入输出端口的简称,简单来说就是软件可控制的引脚,STM32芯片的GPIO引脚 ...
- IOS UITableView的代理方法详解
一.UITableViewDataSourc(数据源代理) 1.必须实现的回调方法 返回每个分区的行数 - (NSInteger)tableView:(UITableView *)tableView ...
- matlab与VC6.0混合编程设置
版本matlab 2009 和vc++6.0 SP6 步骤 1) 配置环境,新建一个VC工程,然后在VC界面的“工具->选项”的目录选项卡中的“include”中加入如下路径: 2) D:\ ...
- 基于jQuery左右滑动切换图片代码
分享一款基于jQuery左右滑动切换图片代码.这是一款基于jQuery实现的左右滑动切换焦点图代码.效果图如下: 在线预览 源码下载 实现的代码: <div class="v_ou ...
- SQL Server 禁止和启用约束
Alter Table XXX nocheck constraint xxx Alter Table XXX check constraint xxx
- SpringMVC经典系列-15对SpringMVC的总结---【LinusZhu】
注意:此文章是个人原创,希望有转载须要的朋友们标明文章出处,假设各位朋友们认为写的还好,就给个赞哈.你的鼓舞是我创作的最大动力,LinusZhu在此表示十分感谢,当然文章中如有纰漏,请联系linusz ...
- GSM错误代码表
转:http://blog.csdn.net/renjwjx/article/details/2290667 GSM device: AT+CMEE=1 AT&W CME ERROR's ...
- C 字符串操作函数
针对C风格的字符串(char p[n];): 长度(strlen).追加(strcat, strncat).比较(strcmp, strncmp).查找(strchr, strstr)等. --带n的 ...
- ImageNet Classification with Deep Convolutional Neural Networks 论文解读
这个论文应该算是把深度学习应用到图片识别(ILSVRC,ImageNet large-scale Visual Recognition Challenge)上的具有重大意义的一篇文章.因为在之前,人们 ...