UE4使用FSocket进行UDP通信

需求

在项目中,需要多个按钮的按压和释放事件触发后发送消息,因此创建一个C++单例模式的类,用于收发消息。

准备

在xxx.Build.cs中添加Networking和Sockets模块。

PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "Networking", "Sockets"});

代码

#pragma once

#include "CoreMinimal.h"
#include "Networking.h"

class  MySocket
{
public:
    MySocket();
    ~MySocket();

    static MySocket* GetInstance();


    void SendMessage(const FString& Message, const FString& Ip, const int& Port);

    void ReceiveMessage(const FArrayReaderPtr& ArrayReader, const FIPv4Endpoint& Endpoint);


private:

    void Init();

    static MySocket* m_pInstance;

    FSocket* m_pUdpSocket;
    FUdpSocketReceiver* m_pSocketReceiver;
};
#include "MySocket.h"

MySocket* MySocket::m_pInstance = nullptr;

MySocket::MySocket()
{

}

MySocket::~MySocket()
{
}

MySocket* MySocket::GetInstance()
{
	if (m_pInstance == nullptr)
	{
		m_pInstance = new MySocket;
		m_pInstance->Init();
	}
	return m_pInstance;
}

void MySocket::Init()
{
	FIPv4Address UdpAddr;
	FIPv4Address::Parse("10.28.5.138", UdpAddr);//本机IP,将字符串转换为IPv4地址
	FIPv4Endpoint Endpoint(UdpAddr, 41450);//本机端口 
	int32 BufferSize = 4096;//缓冲区大小,根据具体情况而定 

	FUdpSocketBuilder SocketBuilder = FUdpSocketBuilder(TEXT("m_pUdpSocket"));
	SocketBuilder.BoundToEndpoint(Endpoint);//绑定地址 
	SocketBuilder.WithReceiveBufferSize(BufferSize);//设置缓冲区大小
	SocketBuilder.AsNonBlocking();//非阻塞 

	m_UdpSocket = SocketBuilder;
    
    FTimespan Timespan = FTimespan::FromMilliseconds(20);//检查缓冲区间隔时间 
    m_pSocketReceiver = new FUdpSocketReceiver(m_pUdpSocket, Timespan, TEXT("m_pSocketReceiver"));
    m_pSocketReceiver->OnDataReceived().BindRaw(this, &MySocket::ReceiveMessage);//绑定接收回调函数 
    m_pSocketReceiver->Start();
}

void MySocket::SendMessage(const FString& Message, const FString& Ip, const int& Port)
{
	TArray<uint8> Send_array;
	FString stringSend = Message;
	TCHAR* str = stringSend.GetCharArray().GetData();
	int32 str_len = FCString::Strlen(str);
	for (int j = 0; j < str_len; j++)
	{
		// Generic types for almost all compilersand platforms
		uint8* dst = (uint8*)TCHAR_TO_UTF8(str);
		Send_array.Add(*dst);
		str++;
	}

	static TSharedPtr<FInternetAddr> InternetAddr;
	if (!InternetAddr.IsValid())
	{
		InternetAddr = ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->CreateInternetAddr();
	}
	bool bIsValid = false;
	InternetAddr->SetIp(*Ip, bIsValid);
	InternetAddr->SetPort(Port);
	int32 BytesSent = 0;
	m_UdpSocket->SendTo(Send_array.GetData(), Send_array.Num(), BytesSent, *InternetAddr);

}

void MySocket::ReceiveMessage(const FArrayReaderPtr& ArrayReader, const FIPv4Endpoint& Endpoint)
{
    uint8* RecvData = ArrayReader->GetData();

    uint8 data[1024];
    FMemory::Memzero(data, 1024);
    FMemory::Memcpy(data, ArrayReader->GetData(), ArrayReader->Num());//复制到data

    FString Message = ((const char*)data);
    
    //处理Message...
    
}


注:推荐将IP和端口写入配置文件。

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值