解决 UDP 接收 JSON 数据时出现乱码与垃圾字符的问题

陌枫酱_2535

陌枫酱_2535

2026-03-22

553人浏览

原创

解决 UDP 接收 JSON 数据时出现乱码与垃圾字符的问题

本文详解 UDP 通信中因 C++ 端 std::array 缺乏自动空终止导致的字符串解析乱码问题,提供安全复制、正确输出及结构化设计的完整解决方案。

本文详解 udp 通信中因 c++ 端 `std::array` 缺乏自动空终止导致的字符串解析乱码问题,提供安全复制、正确输出及结构化设计的完整解决方案。

在基于 UDP 的跨语言(Python → C++)JSON 数据传输场景中,接收端出现类似 Continue for 400 meters."zU,,3 的垃圾字符,根本原因并非网络丢包或编码错误,而是 C++ 结构体中使用定长 std::array 存储字符串时,未做显式空终止(null-termination)且输出逻辑未做边界检查,导致 std::cout 超出有效字符串范围读取内存垃圾。

? 问题定位:std::array 不是 std::string

Python 发送端使用 json.dumps(data).encode() 生成合法 UTF-8 字节流,C++ 接收后经 Json::Reader 正确解析为 std::string —— 这部分完全可靠。问题发生在将 std::string 逐字节拷贝到 std::array 后的后续使用环节:

  • ✅ std::copy(str.begin(), str.end(), array.begin()) 仅复制内容,不写入 \0
  • ❌ for (auto& v : array) std::cout (v) 强制遍历全部 100 个元素,包括未初始化/残留的垃圾字节
  • ❌ array.data() 若未手动补 \0,直接传给 C 风格函数(如 printf("%s", arr.data()))会越界读取

这正是你观察到“改用 std::string 就正常”的根本原因:std::string 内置长度管理与隐式 null 终止,operator

✅ 正确做法:三步安全处理

1. 安全复制 + 显式空终止

// ✅ 推荐:带长度保护的复制,并确保 null 终止
template<size_t n>
void safeCopyToUint8Array(const std::string& src, std::array<uint8_t n>& dst) {
    size_t len = std::min(src.length(), N - 1); // 预留1字节给 '\0'
    std::copy(src.begin(), src.begin() + len, dst.begin());
    dst[len] = '\0'; // 强制 null 终止
}

// 使用示例:
std::string verbalPostStr = instr["verbal_post_transition_instruction"].asString();
safeCopyToUint8Array(verbalPostStr, instruction.verbal_post_transition_instruction);</uint8_t></size_t>

2. 安全输出:避免遍历整个数组

// ✅ 正确输出方式(利用 null 终止)
std::cout (instruction.verbal_post_transition_instruction.data()) (instruction.verbal_post_transition_instruction.data()),
    strnlen(reinterpret_cast<const char>(instruction.verbal_post_transition_instruction.data()), 100)
);
std::cout <h4>3. (进阶)结构体设计优化:混合使用 std::string 与 std::array</h4>
<p>若需兼顾性能与安全性,可将 std::array<uint8_t n> 仅用于底层存储(如序列化/二进制协议),对外暴露 std::string_view 或封装访问器:</uint8_t></p>
<pre class="brush:php;toolbar:false;">struct Instruction {
    // ... 其他字段
    std::array<uint8_t> verbal_post_transition_instruction;

    // 安全访问接口
    std::string_view getVerbalPostInstruction() const {
        const char* ptr = reinterpret_cast<const char>(verbal_post_transition_instruction.data());
        return std::string_view(ptr, strnlen(ptr, 100));
    }
};
// 使用:std::cout <h3>⚠️ 关键注意事项</h3>
<ul>
<li>
<strong>UDP 无连接、不可靠</strong>:单包最大理论尺寸为 65507 字节(IP 头 + UDP 头 = 28B),但实际建议 ≤ 1472 字节(以太网 MTU 1500 - IP/UDP 头)。你使用的 char buffer[45008] 虽能容纳大 JSON,但需确保发送端不超过此限制,否则 IP 分片可能导致丢包(且 UDP 不重传)。</li>
<li>
<strong>JSON 解析健壮性</strong>:当前 parseJsonData 未校验字段是否存在(如 instr["instruction"] 可能为空),建议添加 if (instr.isMember("instruction")) 检查。</li>
<li>
<strong>缓冲区大小一致性</strong>:Python 端 json.dumps(data).encode() 长度应远小于 buffer 容量;可在 C++ 中添加日志:std::cout </li>
<li>
<strong>字符编码统一</strong>:确保 Python encode() 与 C++ 解析均按 UTF-8 处理(默认符合),避免 wchar_t 或本地 locale 干扰。</li>
</ul>
<h3>✅ 总结</h3>
<table>
<thead><tr>
<th>问题现象</th>
<th>根本原因</th>
<th>解决方案</th>
</tr></thead>
<tbody><tr>
<td>Verbal Post Transition Instruction 输出含乱码</td>
<td>std::array<uint8_t> 未 null 终止 + 输出逻辑遍历全部元素</uint8_t>
</td>
<td>① 复制时预留 \0 并写入<br>② 输出时用 reinterpret_cast<const char> + std::string_view 或 strnlen 限定长度</const>
</td>
</tr></tbody>
</table>
<p>通过严格遵循「复制即终止、输出即截断」原则,即可彻底消除 UDP JSON 通信中的字符串垃圾数据问题,在保持 C++ 内存可控性的同时,获得与 std::string 相当的安全性与可维护性。</p></const></uint8_t>
PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
python打包成可执行文件
python打包成可执行文件

本专题为大家带来python打包成可执行文件相关的文章,大家可以免费的下载体验。

2023.07.20

1831

4

python能做什么
python能做什么

python能做的有:可用于开发基于控制台的应用程序、多媒体部分开发、用于开发基于Web的应用程序、使用python处理数据、系统编程等等。本专题为大家提供python相关的各种文章、以及下载和课程。

2023.07.25

4904

7

format在python中的用法
format在python中的用法

Python中的format是一种字符串格式化方法,用于将变量或值插入到字符串中的占位符位置。通过format方法,我们可以动态地构建字符串,使其包含不同值。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.07.31

1789

3

python教程
python教程

Python已成为一门网红语言,即使是在非编程开发者当中,也掀起了一股学习的热潮。本专题为大家带来python教程的相关文章,大家可以免费体验学习。

2023.08.03

29277

23

python环境变量的配置
python环境变量的配置

Python是一种流行的编程语言,被广泛用于软件开发、数据分析和科学计算等领域。在安装Python之后,我们需要配置环境变量,以便在任何位置都能够访问Python的可执行文件。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.04

3507

5

python eval
python eval

eval函数是Python中一个非常强大的函数,它可以将字符串作为Python代码进行执行,实现动态编程的效果。然而,由于其潜在的安全风险和性能问题,需要谨慎使用。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.04

3507

5

scratch和python区别
scratch和python区别

scratch和python的区别:1、scratch是一种专为初学者设计的图形化编程语言,python是一种文本编程语言;2、scratch使用的是基于积木的编程语法,python采用更加传统的文本编程语法等等。本专题为大家提供scratch和python相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.11

1223

5

python合并两个列表
python合并两个列表

Python是一种强大的编程语言,具有许多方便的功能和工具。在Python中,有多种方法可以合并两个列表。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.10

616

4

python是前端还是后端
python是前端还是后端

Python属于前端也属于后端,其灵活性和丰富的生态系统使得开发人员能够在不同的领域中灵活运用。本专题为大家提供python相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.11

2723

5

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
热门推荐
/
最新课程
phpStudy极速入门视频教程
phpStudy极速入门视频教程

共6课时 | 54.7万人学习

独孤九贱(4)_PHP视频教程
独孤九贱(4)_PHP视频教程

共89课时 | 134.1万人学习