UE5 独立程序的网络TCP/UDP服务器与客户端基础流程

news2024/10/7 20:31:23

引擎源码版,复制\Engine\Source\Programs\路径下的BlankProgram空项目示例。

重命名BlankProgram,例如CustomTcpProgram,并修改项目名称。

 修改.Build.cs内容

修改Target.cs内容 

 

 修改Private文件夹内.h.cpp文件名并修改.cpp内容

刷新引擎

在项目.Build.cs中加入模块

// Copyright Epic Games, Inc. All Rights Reserved.

using UnrealBuildTool;

public class TCPSocketServer : ModuleRules
{
	public TCPSocketServer(ReadOnlyTargetRules Target) : base(Target)
	{
		PublicIncludePathModuleNames.Add("Launch");
		PrivateDependencyModuleNames.Add("Core");
		PrivateDependencyModuleNames.Add("Projects");
        //加入网络模块
		PrivateDependencyModuleNames.Add("Sockets");
		PrivateDependencyModuleNames.Add("ApplicationCore");

		// to link with CoreUObject module:
		// PrivateDependencyModuleNames.Add("CoreUObject");

		// to enable tracing:
		// AppendStringToPublicDefinition("UE_TRACE_ENABLED", "1");

		// to enable LLM tracing:
		// GlobalDefinitions.Add("LLM_ENABLED_IN_CONFIG=1");
		// GlobalDefinitions.Add("UE_MEMORY_TAGS_TRACE_ENABLED=1");
	}
}

 .cpp

// Copyright Epic Games, Inc. All Rights Reserved.

#include "TCPSocketServer.h"

#include "RequiredProgramMainCPPInclude.h"
#include "Sockets.h"
#include "SocketSubsystem.h"

DEFINE_LOG_CATEGORY_STATIC(LogTCPSocketServer, Log, All);

IMPLEMENT_APPLICATION(TCPSocketServer, "TCPSocketServer");

INT32_MAIN_INT32_ARGC_TCHAR_ARGV()
{
	//应用初始化设置  
	GEngineLoop.PreInit(ArgC,ArgV);

	// 获取网络套接字子系统
	ISocketSubsystem* SocketSubsystem = ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM);
	// 创建一个TCP类型的套接字,命名为"This TcpIp Type"
	FSocket* Socket = SocketSubsystem->CreateSocket(NAME_Stream,TEXT("This TcpIp Type"));

	// 创建一个互联网地址对象,用于指定服务器的IP地址和端口号
	TSharedPtr<FInternetAddr> Addr = SocketSubsystem->CreateInternetAddr();

	Addr->SetPort(8888);

	bool bIsValid = false;
	Addr->SetIp(TEXT("127.0.0.1"),bIsValid);
	
	Socket->Bind(*Addr);

	Socket->Listen(128);
	
	while (true)
	{
		// 接受一个新的客户端连接请求,并返回一个新的套接字对象来表示这个连接
		FSocket* ClinetSocket = Socket->Accept(TEXT("ClinetConnect"));

		// 创建一个字节数组用于存储接收到的数据
		uint8 Buf[1024]{0};
		//存储实际读取到的字节数
		int32 BytesRead = 0;

		// 从客户端套接字读取数据到Buf数组中,最多读取1024字节,并将实际读取的字节数存储在BytesRead中
		ClinetSocket->Recv(Buf,1024,BytesRead);

		// 将接收到的字节数组转换为TCHAR字符串(用于UE5的字符串处理)
		FString Msg = UTF8_TO_TCHAR(reinterpret_cast<char *>(Buf));

		UE_LOG(LogTCPSocketServer,Display,TEXT("Msg = %s||Len = %d"),*Msg,BytesRead);
	}
}
/*
*TArray<FSocket*> Sockets; // 假设这是你的套接字列表  
  
// 遍历套接字列表  
for (int i = 0; i < Sockets.Num(); i++)  
{  
FSocket* Socket = Sockets[i];  
FInternetAddr* RemoteAddr = Socket->GetRemoteAddress();  
      
// 获取远程地址的IP和端口号  
FString IP;  
uint16 Port;  
RemoteAddr->GetIP(IP);  
RemoteAddr->GetPort(Port);  
      
// 使用IP和端口号进行进一步的处理或记录等操作  
UE_LOG(LogTCPSocketServer, Display, TEXT("Client IP: %s, Port: %d"), *IP, Port);  
}
*/

客户端.cpp

// Copyright Epic Games, Inc. All Rights Reserved.

#include "TCPSocketClient.h"

#include "RequiredProgramMainCPPInclude.h"
#include "Sockets.h"
#include "SocketSubsystem.h"

DEFINE_LOG_CATEGORY_STATIC(LogTCPSocketClient, Log, All);

IMPLEMENT_APPLICATION(TCPSocketClient, "TCPSocketClient");

INT32_MAIN_INT32_ARGC_TCHAR_ARGV()
{
	GEngineLoop.PreInit(ArgC,ArgV);

	ISocketSubsystem* SocketSubsystem = ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM);

	FSocket* Socket = SocketSubsystem->CreateSocket(NAME_Stream,TEXT("This Tcp Client"));

	TSharedPtr<FInternetAddr> Addr = SocketSubsystem->CreateInternetAddr();
	
	Addr->SetPort(8888);
	bool bIsValid = false;
	Addr->SetIp(TEXT("127.0.0.1"),bIsValid);

	if (Socket->Connect(*Addr))
	{
		FString Msg = TEXT("Hello Server");
		int32 SendSize = 0;
		Socket->Send(reinterpret_cast<uint8*>(TCHAR_TO_UTF8(*Msg)),Msg.Len(),SendSize);
	}

	Socket->Close();
	SocketSubsystem->DestroySocket(Socket);

	UE_LOG(LogTCPSocketClient, Display, TEXT("Hello World"));
	
	FEngineLoop::AppExit();
	return 0;
}

未完待续。。。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1400008.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringMVC获取参数与页面跳转

获取参数 第一种 直接当成方法的参数&#xff0c;需要与前台的name一致 相当于Request.getAttribute("username") Controller 第二种 使用对象接收 页面的name也要和对象的字段一致 创建一个对应的实体类 Controller 将参数更换为User对象就行 SpringMVC获取到…

【设计模式】你知道游戏SL大法是什么设计模式吗?

什么是备忘录模式&#xff1f; 老规矩&#xff0c;我们先来看看备忘录模式 (Memento) 的定义&#xff1a;在不破坏封装性的前提下&#xff0c;捕获一个对象的内部状态&#xff0c;并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。 它的UML类图如下&a…

keep-alive组件缓存

keep-alive组件缓存 从a跳b&#xff0c;a已经销毁&#xff0c;b重新渲染&#xff1b;b跳a&#xff0c;b销毁a重新渲染 源组件销毁&#xff0c;目标组件渲染 组件缓存&#xff1a;组件实例等相关&#xff08; 包括vnode&#xff09;存储起来 重新渲染指的是&#xff1a;把视图重…

MySQL---多表查询综合练习

创建dept表 CREATE TABLE dept ( deptno INT(2) NOT NULL COMMENT 部门编号, dname VARCHAR (15) COMMENT 部门名称, loc VARCHAR (20) COMMENT 地理位置 ); 添加dept表主键 mysql> alter table dept add primary key(deptno); Query OK, 0 rows affected (0.02 s…

正则表达式初版

一、简介 REGEXP&#xff1a; Regular Expressions&#xff0c;由一类特殊字符及文本字符所编写的模式&#xff0c;其中有些字符&#xff08;元字符&#xff09;不表示字符字面意义&#xff0c;而表示控制或通配的功能&#xff0c;类似于增强版的通配符功能&#xff0c;但与通…

YOLOv5改进 | 主干篇 | 华为GhostnetV1一种移动端的专用特征提取网络

一、本文介绍 本文给大家带来的改进机制是华为移动端模型Ghostnetv1,华为GhostnetV1一种移动端的专用特征提取网络,旨在在计算资源有限的嵌入式设备上实现高性能的图像分类。GhostNet的关键思想在于通过引入Ghost模块,以较低的计算成本增加了特征图的数量,从而提高了模型的…

消除噪音:Chain-of-Note (CoN) 强大的方法为您的 RAG 管道提供强大动力

论文地址&#xff1a;https://arxiv.org/abs/2311.09210 英文原文地址&#xff1a;https://praveengovindaraj.com/cutting-through-the-noise-chain-of-notes-con-robust-approach-to-super-power-your-rag-pipelines-0df5f1ce7952 在快速发展的人工智能和机器学习领域&#x…

数据结构 | 红黑树

二叉搜索树 节点的左边比节点的值小&#xff0c;右边比节点的值大。 红黑树 红黑树的性质 节点要么是红色&#xff0c;要么是黑色根节点是黑色叶子节点都是黑色的空节点红黑树中红色节点的子节点都是黑色从任一节点到叶子节点的所有路径都包含相同数目的黑色节点 在添加或者…

Rustdesk自建服务搭建好了,打开Win10 下客户端下面状态一直正在接入网络,无法成功连接服务器

环境: Rustdesk1.2.3 自建服务器 有域名地址 问题描述: Rustdesk自建服务搭建好了,打开Win10 下客户端下面状态一直正在接入网络,无法成功连接服务器 解决方案: RustDesk是一款免费的远程桌面软件,它允许用户通过互联网远程连接和控制其他计算机。它是用Rust编程语…

爬虫进阶之selenium模拟浏览器

爬虫进阶之selenium模拟浏览器 简介环境配置1、建议先安装conda2、创建虚拟环境并安装对应的包3、下载对应的谷歌驱动以及与驱动对应的浏览器 代码setting.py配置scrapy脚本参考中间件middlewares.py 附录&#xff1a;selenium教程 简介 Selenium是一个用于自动化浏览器操作的…

web开发学习笔记(10.postman请求响应,后端接口基础知识)

1.springboot使用get请求接受简单参数 上述写法不去别get或者post请求 2.postman各种提交方式的区别 1、form-data: 就是http请求中的multipart/form-data,它会将表单的数据处理为一条消息&#xff0c;以标签为单元&#xff0c;用分隔符分开。既可以上传键值对&#xff0c;也可…

huggingface学习 | 云服务器使用hf_hub_download下载huggingface上的模型文件

系列文章目录 huggingface学习 | 云服务器使用git-lfs下载huggingface上的模型文件 文章目录 系列文章目录一、hf_hub_download介绍二、找到需要下载的huggingface文件三、准备工作及下载过程四、全部代码 一、hf_hub_download介绍 hf_hub_download是huggingface官方支持&…

【C++】文件操作

文件操作 一、文本文件&#xff08;一&#xff09;写文件读文件 二、二进制文件&#xff08;一&#xff09;写文件&#xff08;二&#xff09;读文件 程序运行时产生的数据都属于临时数据&#xff0c;程序一旦运行结束都会被释放&#xff0c;通过文件可以将数据持久化&#xff…

支付宝小程序开发踩坑笔记(支付宝、学习强国小程序)

1、接口请求安卓端回调 success&#xff0c;IOS 端回调 fail 原因&#xff1a;dataType 设置不对&#xff0c;默认是 json 格式&#xff0c;对返回数据会进行 json 解析&#xff0c;如果解析失败&#xff0c;就会回调 fail 。加密传输一般是 text 格式。 2、input 禁止输入空格…

【动态规划】【数学】【C++算法】805 数组的均值分割

作者推荐 【动态规划】【数学】【C算法】18赛车 本文涉及知识点 动态规划 数学 805 数组的均值分割 给定你一个整数数组 nums 我们要将 nums 数组中的每个元素移动到 A 数组 或者 B 数组中&#xff0c;使得 A 数组和 B 数组不为空&#xff0c;并且 average(A) average(B)…

2788.按分隔符拆分字符串

前言 力扣还挺上道&#xff08;bushi&#xff09;&#xff0c;今天第一次写每日一题&#xff0c;给了个简单等级的数组题&#xff0c;我只能说&#xff0c;首战告捷&#xff08;小白的呐喊&#xff09;&#xff0c;看看这每日一题我能坚持一天写出来&#xff0c; ok&#xff…

Ubuntu安装mysql8详细步骤

1、拉取镜像 docker pull mysql:8.0.20 2、启动镜像 docker run -p 3307:3306 --name mysql8 -e MYSQL_ROOT_PASSWORD123456 -d mysql:8.0.20 检查是否启动成功 docker ps 3、配置挂载 创建挂载目录&#xff08;请检查保证创建成功&#xff09; mkdir -p /docker/mysql8.0.20/…

Java安全 CC链1分析

Java安全之CC链1分析 什么是CC链环境搭建jdk下载idea配置创建项目 前置知识Transformer接口ConstantTransformer类invokerTransformer类ChainedTransformer类 构造CC链1CC链1核心demo1demo1分析 寻找如何触发CC链1核心TransformedMap类AbstractInputCheckedMapDecorator类readO…

IDEA在重启springboot项目时没有自动重新build

IDEA在重启springboot项目时没有自动重新build 问题描述 当项目里面某些依赖或者插件更新了&#xff0c;target的class文件没有找到&#xff0c;导致不是我们需要的效果。 只能手动的清理target文件&#xff0c;麻烦得很 &#xff0c; 单体项目还好说&#xff0c;一次清理就…

Qt5.15.2中加入图片资源

系列文章目录 文章目录 系列文章目录前言一、加入图片资源二、代码 前言 以前用的Qt5.15.2之前的版本&#xff0c;QtCreator默认的工程文件是*.pro&#xff0c;现在用5.15.2创建工程默认的工程文件是CMameList.txt,当然在创建项目时&#xff0c;仍然可以使用pro工程文件用QtCr…