赣州网站建设流程/山东seo多少钱
最近在使用UE的Socket模块与Python服务器进行通信时遇到了一些坑,特此记录一下。
先来复现一下问题,这里只截取关键代码。
UE端:
bool ASoc::SendMsg(const FString& Msg)
{TSharedRef<FInternetAddr> TargetAddr = ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->CreateInternetAddr();FString Serialized = Msg;bool bSend;TCHAR* SeriallizedChar = Serialized.GetCharArray().GetData();int32 Size = FCString::Strlen(SeriallizedChar) + 1;int32 Sent = 0;bSend = SocClient->SendTo((uint8*)TCHAR_TO_UTF8(SeriallizedChar),Size,Sent,*TargetAddr);if(bSend){UE_LOG(LOGNLPFORUE,Log,TEXT("[To LTP | %d]: %s"),Size,*Msg);}else{UE_LOG(LOGNLPFORUE,Log,TEXT("Failed to send Msg to tlp"));}return bSend;
}
Python端:
def socrecv():global data,conn,addr,socwhile True:data = str(conn.recv(recvbuff),'utf-8','ignore')print('[recv msg from ue |',sys.getsizeof(data),']: ',repr(data))def soclisten():global soc,bind,conn,addr,recvthreadsoc=socket.socket(socket.AF_INET,socket.SOCK_STREAM)soc.bind((ip,port))soc.listen(5)print('server listen...')bind = Truewhile True:conn,addr = soc.accept()print(addr,'已接入')recvthread = Thread(target=socrecv)recvthread.setDaemon(True)recvthread.start() soclisten()
运行结果:
UE端发送的数据:
LOGNLPFORUE: [To LTP | 45]: {"cmd":"ltp","type":"cws","data":"他叫汤姆去拿外衣"}
LOGNLPFORUE: [To LTP | 102]: {"cmd":"ltp","type":"cws","data":"He told Tom to get the coat, but Tom brought a piece of underwear"}
Python端接收到数据:
[recv msg from ue | 148 ]: '{"cmd":"ltp","type":"cws","data":"他叫汤'
[recv msg from ue | 151 ]: '{"cmd":"ltp","type":"cws","data":"He told Tom to get the coat, but Tom brought a piece of underwear"}\x00'
可以看到数据容量并没有超出缓存上限,且Python端接收的数据都有做utf-8的编码转换,但依旧出现了中文数据接收不全,容量更大的英文数据反而没问题。
问题出在了UE端的FSocket::SendTo函数,SendTo函数的定义:
bool FSocket::SendTo(const uint8* Data, int32 Count, int32& BytesSent, const FInternetAddr& Destination)
Data就是我们要发送的字节数据,Count数据的大小,BytesSent记录的是数据的发送进度,Destination是要发送数据的地址。
问题就出在Count的值上,可以看到在上面的代码中我们是直接计算的FString的长度,然后以这个长度作为发送的数据大小,在纯英文的数据中这没有任何问题,但在中文数据中,由于中文编码的特殊性,FString应该有做特殊的编码处理,导致直接计算FString的长度作为发送数据的字节大小其实是小于真实数据大小的,这就导致在UE端发送中文数据时就没有发送完整到数据,所以Python端接收到数据就出现数据不全的问题。
既然知道原因了,接下来就可以解决了。那么我们就需要去找一个计算FString中文数据真实字节数的算法来计算SenTo要发送字节数据大小。
在网上我也没找到相关的算法代码,于是就去请教了一位大佬,大佬给了我一份算法代码:
int32 ASoc::CalcUtf0NumFromString(const FString& Str)
{int32 result = 0; for (int i = 0; i < Str.Len(); i++){if (Str[i] <= 0x7f)result = result + 1;else if (Str[i] > 0x7f && Str[i] <= 0x07ff)result = result + 2;else if (Str[i] > 0x07ff && Str[i] <= 0xffff)result = result + 3;elseresult = result + 4;}return result + 1;
}
没有去深究FString的中英文编码,代码我是没看明白的,使用这个算法计算数据的字节大小,就能计算出正确的大小。
然后UE端的代码将int32 Size = FCString::Strlen(SeriallizedChar) + 1;
换成int32 Size = CalcUtf0NumFromString(SeriallizedChar);
,问题就解决了。
相关文章:

【UE5】UE5与Python Socket通信中文数据接收不全
最近在使用UE的Socket模块与Python服务器进行通信时遇到了一些坑,特此记录一下。 先来复现一下问题,这里只截取关键代码。 UE端: bool ASoc::SendMsg(const FString& Msg) {TSharedRef<FInternetAddr> TargetAddr ISocketSubsy…...

一些有难度的c++题目思路讲解--第一期2023/8/8 小Q的修炼与旷野大计算
说明: 本期博客将分为10篇讲解一些有点挑战的题目,第一期是所有人都可以看到,但后面的关注我才能看到哦!有望大家的支持!谢谢! 题目链接(按顺序) [NOI2013] 小Q的修炼 - 洛谷 小Q的修炼[NOI2013] 小Q的修炼 - 洛谷 [NOI2016] 旷野大计算 - 洛谷旷野大计算[NOI2016] 旷野…...

Node.js:path文件路径操作模块
path 用于文件路径操作 官方文档 https://nodejs.org/api/path.html 一个不错的解释 ┌─────────────────────┬────────────┐│ dir │ base │├──────┬ ├──────┬─────┤│ ro…...

基于 CentOS 7 构建 LVS-DR 群集
文章目录 一、LVS-DR集群介绍1.LVS的基本工作原理2. LVS-DR模式工作原理 二、 LVS-DR模式应用特点三、LVS – DR 模式集群构建1.前期环境准备2.配置LVS3.配置RS 一、LVS-DR集群介绍 1.LVS的基本工作原理 当用户向负载均衡调度器(Director Server)发起请…...
机器学习笔记 - 使用 Tensorflow 从头开始构建您自己的对象检测器
一、简述 之前的文章是利用了VGG16的预训练模型,然后构造完全连接的层标头以输出预测的边界框坐标,但是不包含对象标签的分类。 机器学习笔记 - 使用Keras、TensorFlow框架进行自定义数据集目标检测训练_keras 制作 目标检测 数据集_坐望云起的博客-CSDN博客学习如何训练自定…...

IELAB-网络工程师的路由答疑10问(2)
各位小伙伴们,接下来的问题可能有些难度,你们做好准备了吗? 7. 动态路由协议做了啥? 这次咱们先解决第一个比较棘手的问题--路由协议,相信初学的同学对于路由协议的学习总是或多或少有些问题,呐ÿ…...

聚观早报|iPhone 15预计9月22日上市;一加Open渲染图曝光
【聚观365】8月7日消息 iPhone 15预计9月22日上市一加Open渲染图曝光Redmi K60至尊版细节曝光小米14 Pro屏幕细节曝光vivo V3正式发布,执着自研“影像芯片” iPhone 15预计9月22日上市 上周有多位消息人士透露,多家合作的电信运营商已要求员工不要在9月…...

react-use-gesture
介绍 react-use-gesture 是一个基于 React Hooks 的库,用于处理手势事件。它提供了一种简单且灵活的方式来处理用户的手势操作,例如拖动、缩放、旋转等。 使用 安装 react-use-gesture: npm install react-use-gesture 导入所需的模块和钩…...

智能中的“一体两面”
一体两面指的是一个事物或问题同时具有两个相互依存、互为对立的方面或特征。一体表示两个方面或特征是不可分割、相互联系的整体,两面表示这两个方面或特征又是相互对立、互相影响的。常用于描述矛盾问题或复杂事物的本质。例如,事物的存在与发展、利益…...

前端渲染数据
在前端对接受后端数据处理后返回的接收值的时候,为了解决数据过于庞大,而对数据进行简化处理例如性别,经常会使用1, 0这俩个来代替文字的男,女。以下就是前端渲染的具体实现。 以下是部分代码 <el-table-columnpr…...

【Linux操作系统】深入了解系统编程gdb调试工具
在软件开发过程中,调试是一个非常重要的步骤。无论是在开发新的软件还是维护现有的代码,调试都是解决问题的关键。对于Linux开发者来说,GDB是一个非常有用的调试工具。在本文中,我们将探讨Linux中使用GDB进行调试的方法和技巧。 …...

linux 安装go 1.18版本
首先去官网找到对应的版本 直接下载下来(如果服务器可以直接访问到go 官网也可以wget直接下载到服务器) 然后把该包上传到linux 的/usr/local 目录下 然后直接解压安装该包: sudo tar -C /usr/local -zxvf go1.18.10.linux-amd64.tar.gz 然…...

LLVM笔记2 Intermediate Representation (IR)
参考链接:https://llvm.org/devmtg/2019-04/slides/Tutorial-Bridgers-LLVM_IR_tutorial.pdf https://zhuanlan.zhihu.com/p/163063995 https://zhuanlan.zhihu.com/p/163328574 文章目录 IR的布局1. IR语法2.IR递归函数3.使用迭代的方式4.全局变量5.LLVM’s type s…...

篇五:原型模式:复制对象的秘密
篇五:"原型模式:复制对象的秘密" 设计模式是软件开发中的重要组成部分,原型模式是创建型设计模式中的一种。原型模式旨在通过复制现有对象来创建新的对象,而不是通过调用构造函数来创建。在C中,原型模式广泛…...

为什么ip地址一直在变化
IP地址是计算机网络中用于唯一标识一台设备的二进制数字串。在互联网中,每台计算机都需要一个唯一的IP地址,以便与其他计算机进行通信。然而,有些情况下,IP地址可能会发生变化。 有多种原因可能导致IP地址发生变化。下面虎观代理…...

10.物联网操作系统之低功耗管理
一。低功耗管理概念及其应用 1.STM32低功耗设计详解 STM32的电源管理系统主要分为: 1.备份域:备份电源,仔细在stm32的板子上寻找,大多都有纽扣电池。 注意:参考手册(PWR)章节有详细的介绍。 2.…...

SQL SERVER 2019 数据库还原测试库的方法
1、备份正式库数据 2、在其它电脑上还原备份的数据库 不需要覆盖其它数据库,直接还原出数据库 还原时修改文件名和数据库名称: 修改文件名称 还原成功...

leetcode 62. 不同路径
2023.8.8 用dp算法一遍过了,很舒服。 重点还是要确定dp数组的含义,本题的dp数组要设成二维的,dp[i][j]的含义是:到(i,j)这个点一共有多少种路径。由于题中说了m和n都大于1,所以假设一…...

ad+硬件每日学习十个知识点(25)23.8.5(常见芯片类型、数字隔离芯片、IO扩展芯片TCAL6416)
文章目录 1.常见的芯片类型2.数字隔离芯片有什么用?3.I2C的I/O扩展芯片说明4.16位I/O扩展芯片TCAL6416的features、applications、description5.TCAL6416的引脚功能6.TCAL6416的电气特性7.TCAL6416的典型特性(图像)8.TCAL6416的参数测量信息&…...

fetch-github-hosts间隔一年大更新v2.6发布,多端支持
前言 fetch-github-hosts是一款同步 github hosts 的工具,用于帮助您解决github时而无法访问的问题。在间隔了一年之久的时间,最近抽空将fetch-github-hosts的依赖及UI进行了一波大更新,同时也增加了一些实用的功能。 主要更新 更新了基础依…...

K最近邻算法:简单高效的分类和回归方法(三)
文章目录 🍀引言🍀训练集和测试集🍀sklearn中封装好的train_test_split🍀超参数 🍀引言 本节以KNN算法为主,简单介绍一下训练集和测试集、超参数 🍀训练集和测试集 训练集和测试集是机器学习和深…...

【数据分析专栏之Python篇】五、pandas数据结构之Series
前言 大家好!本期跟大家分享的知识是 Pandas 数据结构—Series。 一、Series的创建 Series 是一种类似于一维数组的对象,由下面两部分组成: values:一组数据,ndarray 类型index:数据索引 顾名思义&…...

中间件多版本冲突的4种解决方案和我们的选择
背景 在小小的公司里面,挖呀挖呀挖。最近又挖到坑里去了。一个稳定运行多年的应用,需要在里面支持多个版本的中间件客户端;而多个版本的客户端在一个应用里运行时会有同名类冲突的矛盾。在经过询问chatGPT,百度,googl…...

对 async/await 的理解
async/await 的理解 async/await 其实是 Generator 的语法糖,它能实现的效果都能用then 链来实现,它是为优化 then 链而开发出来的。从字面上来看,async 是“异步”的简写,await 则为等待,所以很好理解async用于申明一…...

Vue 整合 Element UI 、路由嵌套、参数传递、重定向、404和路由钩子(五)
一、整合 Element UI 1.1 工程初始化 使用管理员的模式进入 cmd 的命令行模式,创建一个名为 hello-vue 的工程,命令为: # 1、目录切换 cd F:\idea_home\vue# 2、项目的初始化,记得一路的 no vue init webpack hello-vue 1.2 安装…...

修改 Ubuntu 系统的时区
修改 Ubuntu 系统的时区 如果 Ubuntu 系统的时区设置不正确,您可以按照以下步骤进行调整: 1. 查看当前的时区设置,可以使用以下命令: timedatectl 这将显示当前系统的日期、时间和时区信息。 2. 如果时区设置不正…...

如何离线安装ModHeader - Modify HTTP headers Chrome插件?
如何离线安装ModHeader - Modify HTTP headers Chrome插件? 1.1 前言1.2 打开Chrome浏览器的开发者模式1.3 下载并解压打包好的插件1.4 解压下载好的压缩包1.5 加载插件1.6 如何使用插件? 1.1 前言 ModHeader 是一个非常好用的Chrome浏览器插件,可以用…...

在Linux中安装MySQL
在Linux中安装MySQL 检测当前系统中是否安装MySQL数据库 命令作用rpm -qa查询当前系统中安装的所有软件rpm -qa|grep mysql查询当前系统中安装的名称带mysql的软件rpm -qa | grep mariadb查询当前系统中安装的名称带mariadb的软件 RPM ( Red-Hat Package Manager )RPM软件包管理…...

python --windows获取启动文件夹路径/获取当前用户名/添加自启动文件
如何使用Python获取计算机用户名 一、Python自带的getpass模块可以用于获取用户输入的密码,但是它同样可以用来获取计算机用户名。 import getpassuser getpass.getuser() print("计算机用户名为:", user)二、使用os模块获取用户名 Python的…...

微信云托管(本地调试)⑥:nginx、vue刷新404问题
一、nginx默认路径 1.1、默认配置文件路径:/etc/nginx/nginx.conf 1.2、默认资源路径:/usr/share/nginx/html/index.html 二、修改nginx.conf配置 (注意配置中的:include /etc/nginx/conf.d/*.conf; 里面包了一个server配置文件…...