使用wireshark抓包,本地环回测试通信数据已经通过SM4国密算法加密

具体操作

  • 本实验采用 本地环回测试
  • 开启wireshark抓包工具,设定端口号 tcp.port == 5099 (5099为服务端对外开启服务的端口号),不可以使用ip.addr指定ip地址,因为本地环回测试,相关信息太多,使用端口抓包最为简单
  • 首先开启服务端,然后开启客户端,服务端开启之后输出 "Bind returned success",并输出客户端连接通信使用的端口号,然后客户端会使用socket通信传输经过SM4对称加密算法加密返回的密文
  • 密文存储格式是字符串,表示形式是十六进制;socket通信的时候会将这个字符串再次编码为十六进制,因此使用wireshark抓包数据之后 需要对拦截的数据进行解码 (十六进制 转 字符串)
  • hex转str - 在线工具
  • 客户端发送数据完毕之后,输出Client:sending data test,请按任意键退出
  • 服务端打印输出 客户端发送数据的数据 以及对应的长度等信息,输出 Connect closed,结束通信

服务端

 客户端

 wireshark抓包

  • 客户端 端口号 向 服务端 端口号 发送33字节数据

  •  点击 Data,查看下窗口,左边是数据的十六进制,右边是字符串

  •  将wireshark抓到的数据和server接收到的数据对比,数据一致
  • 表明客户端和发送端数据传输是经过SM4算法加密的

参考链接

  • https://blog.csdn.net/CHYabc123456hh/article/details/122049078
  • SM4 ECB加密模式 数据对比试验论证_CHYabc123456hh的博客-CSDN博客
  • 数据填充规则之PKCS7_CHYabc123456hh的博客-CSDN博客
  • C++ Byte转十六进制字符串输出_CHYabc123456hh的博客-CSDN博客
  • 使用国密浏览器和使用Wireshark进行国密抓包_CHYabc123456hh的博客-CSDN博客_gmssl wireshark
  • Socket代码实现服务端 和 客户端之间通信_CHYabc123456hh的博客-CSDN博客_c++实现客户端socket
  • Socket编程 涵盖代码和函数参数介绍_CHYabc123456hh的博客-CSDN博客
  • 本地搭建server和客户端使用端口进行数据通信,使用Wireshark抓取127.0.0.1环回地址并分析通信数据_CHYabc123456hh的博客-CSDN博客
  • 验证客户端和服务端可以传输经SM4加密的密文数据,从而验证发送数据已使用服务器密码机进行SM4加密,而不是随便的字符串乱码_CHYabc123456hh的博客-CSDN博客

服务端代码

// sdf_cpp_warpper.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
// server端#ifndef UNICODE
#define UNICODE
#endif#define WIN32_LEAN_AND_MEAN#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <iomanip>
#include <winsock2.h>
#include <Ws2tcpip.h>
#include <stdio.h>#include "sdf_warpper.hpp"
#include "cstring"#pragma comment(lib, "Ws2_32.lib")
#pragma comment(lib,"libhsm_core.lib")#define DEFAULT_BUFLEN 1024
using namespace std;typedef std::vector<unsigned char> bytes;
std::string BytesToStr(const bytes& in)
{bytes::const_iterator from = in.cbegin();bytes::const_iterator to = in.cend();std::ostringstream oss;for (; from != to; ++from)oss << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(*from);return oss.str();
}void sm4_encrypt_decrypt_demo() {sdf_qax::SDF_warpper sdf_warpper("{\"device_type\": \"rpc\",\"device_socket\": \"172.22.14.231:5000\"}");//char a[16] = { '1','0','0','0','0','2','4','5','6','7','2','1','3','4','5','6' };char a[]{ '0','0','0','0','0','0','0','0','0','0','0','0','0','0' };//char a[]{ 00,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };//std::cout << "input_data: ";std::cout << "char类型数据: ";
/*	for (auto i : a) {std::cout << i << " ";}  *///std::cout << std::endl;			  bytes input(a, a + 15);for (auto i : input) {std::cout << i;}			 std::cout << std::endl;std::cout << "char类型数据 转十六进制 输出: ";std::cout << BytesToStr(input) << std::endl;		   char outbuffer[32]{ 0 };int out_buffer_true_length = 0;sdf_warpper.sm4_symmetry_encrypt((uint8_t *)sdf_warpper.getStaticKey(), a, sizeof(a) / sizeof(char), outbuffer, &out_buffer_true_length);std::cout << "cipher data with padding length: " << out_buffer_true_length << std::endl;char static_key[16] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };bytes input_3(static_key, static_key + 15);std::cout << "static_key数据 转十六进制 输出: ";std::cout << BytesToStr(input_3) << std::endl;/*	for (char i : outbuffer) {std::cout << i;}							   */bytes input_2(outbuffer, outbuffer + out_buffer_true_length);std::cout << "密文数据输出:";std::cout << BytesToStr(input_2) << std::endl;//std::cout << std::endl;std::cout << "true array length: " << strlen(outbuffer) << std::endl;char decrypt_result[32]{ 0 };int out_true_length = 0;sdf_warpper.sm4_symmetry_decrypt((uint8_t *)sdf_warpper.getStaticKey(), outbuffer, out_buffer_true_length, decrypt_result, &out_true_length);std::cout << "decrypt result data: ";for (int i = 0; i < strlen(decrypt_result); i++) {std::cout << decrypt_result[i];}std::cout << std::endl;
}ECCCipher cipher;   //密文存储结构体void sm2_encrypt_decrypt_demo() {sdf_qax::SDF_warpper sdf_warpper2("{\"device_type\": \"rpc\",\"device_socket\": \"172.22.14.231:5000\"}");char a[]{ '3','4','5' };std::cout << "input_data: ";for (char i : a) {std::cout << i;}std::cout << std::endl;sdf_warpper2.sm2_internal_encrypt(1, a, 3, &cipher);char decrypt_result[256]{ 0 };int out_true_length = 0;sdf_warpper2.sm2_internal_decrypt(1, &cipher, reinterpret_cast<sdf_uint8_t *>(decrypt_result), &out_true_length, nullptr, 0);std::cout << "Data length after decryption: " << out_true_length << std::endl;std::cout << "Data after decryption: ";for (int i = 0; i < out_true_length; i++) {std::cout << decrypt_result[i];}std::cout << std::endl;
}void main()
{//Initialze winsockWSADATA wsaData;if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0){std::cout << "Can't Initialize winsock!Quiting!" << std::endl;;return;}//Creste a sockrtSOCKET sockSrv = socket(AF_INET, SOCK_STREAM, 0);if (sockSrv == INVALID_SOCKET) {wprintf(L"Can't create a socket with error %d\n", WSAGetLastError());WSACleanup();return;}//Bind the socket to an ip address and portint port = 5099;SOCKADDR_IN addrSrv;addrSrv.sin_family = AF_INET;addrSrv.sin_port = htons(port); //1024以上的端口号addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);//Bind the socketint retVal = bind(sockSrv, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR));if (retVal == SOCKET_ERROR) {printf("Failed bind:%d\n", WSAGetLastError());closesocket(sockSrv);WSACleanup();return;}else {std::cout << "Bind returned success" << std::endl;}//Tell winsock the socket is for listeningif (listen(sockSrv, SOMAXCONN) == SOCKET_ERROR) {printf("Listen failed:%d", WSAGetLastError());return;}//wait for a connectionSOCKADDR_IN addrClient;int clientSize = sizeof(addrClient);SOCKET sockConn = accept(sockSrv, (SOCKADDR*)&addrClient, &clientSize);if (sockConn == SOCKET_ERROR) {wprintf(L"accept failed with error: %ld\n", WSAGetLastError());closesocket(sockSrv);WSACleanup();return;}char host[NI_MAXHOST];       //Client's remote namechar service[NI_MAXSERV];    //Service (i.e. port)the client is connect onZeroMemory(host, NI_MAXHOST);//Same as memset(host,0,NI_MAXHOST)ZeroMemory(service, NI_MAXSERV);if (getnameinfo((sockaddr*)&addrClient, sizeof(addrClient), host, NI_MAXHOST, service, NI_MAXSERV, 0) == 0) {std::cout << "connect on port " << service << std::endl;}else {inet_ntop(AF_INET, &addrClient.sin_addr, host, NI_MAXHOST);std::cout << host << " connect on port " << ntohs(addrClient.sin_port) << std::endl;}//while loop:accept and echo message back to clientchar recvbuf[DEFAULT_BUFLEN] = "";int recvbuflen = DEFAULT_BUFLEN;memset(recvbuf, 0, sizeof(recvbuf));char sendbuf[] = "Client: sending data test\n";retVal = send(sockConn, sendbuf, sizeof(sendbuf), 0);if (retVal == SOCKET_ERROR) {wprintf(L"send failed with error: %d\n", WSAGetLastError());closesocket(sockSrv);WSACleanup();return;}do {retVal = recv(sockConn, recvbuf, recvbuflen, 0);if (retVal > 0) {wprintf(L"Bytes received: %d\n", retVal);printf("%s\n", recvbuf);}else if (retVal == 0)wprintf(L"Connection closed\n");elsewprintf(L"recv failed with error: %d\n", WSAGetLastError());} while (retVal > 0);closesocket(sockConn);//close socketclosesocket(sockSrv);//close winsockWSACleanup();system("pause");
}// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单
// 调试程序: F5 或调试 >“开始调试”菜单// 入门使用技巧: 
//   1. 使用解决方案资源管理器窗口添加/管理文件
//   2. 使用团队资源管理器窗口连接到源代码管理
//   3. 使用输出窗口查看生成输出和其他消息
//   4. 使用错误列表窗口查看错误
//   5. 转到“项目”>“添加新项”以创建新的代码文件,或转到“项目”>“添加现有项”以将现有代码文件添加到项目
//   6. 将来,若要再次打开此项目,请转到“文件”>“打开”>“项目”并选择 .sln 文件

客户端代码

// sdf_cpp_warpper.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
// client端#ifndef UNICODE
#define UNICODE
#endif#define WIN32_LEAN_AND_MEAN#include <iostream>
#include <stdio.h>
#include <string>
#include <sstream>
#include <vector>
#include <iomanip>
#include <winsock2.h>
#include <Ws2tcpip.h>#include "sdf_warpper.hpp"
#include "cstring"#pragma comment(lib,"libhsm_core.lib")
#pragma comment(lib, "Ws2_32.lib")
using namespace std;typedef std::vector<unsigned char> bytes;
std::string BytesToStr(const bytes& in)
{bytes::const_iterator from = in.cbegin();bytes::const_iterator to = in.cend();std::ostringstream oss;for (; from != to; ++from)oss << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(*from);return oss.str();
}void sm4_encrypt_decrypt_demo(char* outbuffer,int & out_buffer_true_length) {sdf_qax::SDF_warpper sdf_warpper("{\"device_type\": \"rpc\",\"device_socket\": \"172.22.14.231:5000\"}");//char a[16] = { '1','0','0','0','0','2','4','5','6','7','2','1','3','4','5','6' };char a[]{ '0','0','0','0','0','0','0','0','0','0','0','0','0','0','0' };//char a[]{ 00,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };//std::cout << "input_data: ";//std::cout << "char类型数据: ";/*	for (auto i : a) {std::cout << i << " ";}  *///std::cout << std::endl;			  bytes input(a, a + 15);
/*	for (auto i : input) {std::cout << i;}std::cout << std::endl;std::cout << "char类型数据 转十六进制 输出: ";std::cout << BytesToStr(input) << std::endl;		   *///char outbuffer[32]{ 0 };//int out_buffer_true_length = 0;sdf_warpper.sm4_symmetry_encrypt((uint8_t*)sdf_warpper.getStaticKey(), a, sizeof(a) / sizeof(char), outbuffer, &out_buffer_true_length);
//	std::cout << "cipher data with padding length: " << out_buffer_true_length << std::endl;char static_key[16] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };bytes input_3(static_key, static_key + 15);
/*	std::cout << "static_key数据 转十六进制 输出: ";std::cout << BytesToStr(input_3) << std::endl;			 *//*	for (char i : outbuffer) {std::cout << i;}							   */bytes input_2(outbuffer, outbuffer + out_buffer_true_length);//std::cout << "密文数据输出:";//std::cout << BytesToStr(input_2) << std::endl;//std::cout << std::endl;
//	std::cout << "true array length: " << strlen(outbuffer) << std::endl;char decrypt_result[32]{ 0 };int out_true_length = 0;sdf_warpper.sm4_symmetry_decrypt((uint8_t*)sdf_warpper.getStaticKey(), outbuffer, out_buffer_true_length, decrypt_result, &out_true_length);//std::cout << "decrypt result data: ";
/*	for (int i = 0; i < strlen(decrypt_result); i++) {std::cout << decrypt_result[i];				    }							   */std::cout << std::endl;
}
ECCCipher cipher;   //密文存储结构体void sm2_encrypt_decrypt_demo() {sdf_qax::SDF_warpper sdf_warpper2("{\"device_type\": \"rpc\",\"device_socket\": \"172.22.14.231:5000\"}");	char a[]{ '3','4','5' };std::cout << "input_data: ";for (char i : a) {std::cout << i;}std::cout << std::endl;sdf_warpper2.sm2_internal_encrypt(1, a, 3, &cipher);char decrypt_result[256]{ 0 };int out_true_length = 0;sdf_warpper2.sm2_internal_decrypt(1, &cipher, reinterpret_cast<sdf_uint8_t *>(decrypt_result), &out_true_length, nullptr, 0);std::cout << "Data length after decryption: " << out_true_length << std::endl;std::cout << "Data after decryption: ";for (int i = 0; i < out_true_length; i++) {std::cout << decrypt_result[i];}std::cout << std::endl;
}void main() {//Initialze winsockWSADATA wsaData;if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0){std::cout << "Can't Initialize winsock!Quiting!" << std::endl;;return;}//Creste a sockrtSOCKET sockClient = socket(AF_INET, SOCK_STREAM, 0);if (sockClient == INVALID_SOCKET) {wprintf(L"Can't create a socket with error %d\n", WSAGetLastError());WSACleanup();return;}//Bind the socket to an ip address and portint port = 5099;SOCKADDR_IN addrSrv;addrSrv.sin_family = AF_INET;addrSrv.sin_port = htons(5099);//addrSrv.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");inet_pton(AF_INET, "127.0.0.1", &addrSrv.sin_addr.S_un.S_addr);char buff[1024];memset(buff, 0, sizeof(buff));//向服务器发出连接请求if (connect(sockClient, (struct  sockaddr*) & addrSrv, sizeof(addrSrv)) == INVALID_SOCKET) {printf("Connect failed:%d", WSAGetLastError());return;}else{//接收数据recv(sockClient, buff, sizeof(buff), 0);printf("%s\n", buff);}//发送数据//const char* buffSend = "hello, this is a Client....";//send(sockClient, buffSend, strlen(buffSend) + 1, 0);//	char sendbuf[BUFSIZ];
//	ZeroMemory(sendbuf, BUFSIZ);
/*	strcpy_s(sendbuf, str.c_str());if (send(sockClient, sendbuf, strlen(sendbuf) + 1, 0) == SOCKET_ERROR) {wprintf(L"send failed with error: %d\n", WSAGetLastError());closesocket(sockClient);WSACleanup();break;}*/char outbuffer[32]{ 0 };int out_buffer_true_length = 0;sm4_encrypt_decrypt_demo(outbuffer,out_buffer_true_length);bytes input_2(outbuffer, outbuffer + out_buffer_true_length);//std::cout << "密文数据输出:";//std::cout << BytesToStr(input_2) << std::endl;//printf("%d", strlen(buffSend) + 1);std::string return_value(BytesToStr(input_2));//std::cout << return_value << std::endl;char sendbuf[BUFSIZ];ZeroMemory(sendbuf, BUFSIZ);strcpy_s(sendbuf, return_value.c_str());if (send(sockClient, sendbuf, strlen(sendbuf) + 1, 0) == SOCKET_ERROR) {wprintf(L"send failed with error: %d\n", WSAGetLastError());closesocket(sockClient);WSACleanup();exit(-1);}//关闭套接字closesocket(sockClient);WSACleanup();system("pause");}// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单
// 调试程序: F5 或调试 >“开始调试”菜单// 入门使用技巧: 
//   1. 使用解决方案资源管理器窗口添加/管理文件
//   2. 使用团队资源管理器窗口连接到源代码管理
//   3. 使用输出窗口查看生成输出和其他消息
//   4. 使用错误列表窗口查看错误
//   5. 转到“项目”>“添加新项”以创建新的代码文件,或转到“项目”>“添加现有项”以将现有代码文件添加到项目
//   6. 将来,若要再次打开此项目,请转到“文件”>“打开”>“项目”并选择 .sln 文件

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

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

相关文章

public 函数_UE4精品教程 | 渲染编程(C++篇)【第三卷:从仿函数到std::function再到虚幻4Delegate】...

本文转载于YivanLee知乎作者专题目录链接&#xff1a;https://zhuanlan.zhihu.com/p/67694999这几天研究了一下虚幻4的delegate&#xff0c;但是想要理解这个&#xff0c;还得从仿函数说起。下面是一段代码例子&#xff1a;class MyFunctor{ public: int operator()(int …

C语言深度剖析书籍学习记录 第一章 关键字

C语言标准定义了32个关键字 union声明联合数据类型 Union declaration - cppreference.com维护足够的空间来置放多个数据成员中的“一种”&#xff0c;而不是为每一个数据成员配置空间&#xff0c;在 union 中所有的数据成员共用一个空间&#xff0c;同一时间只能储存其中一个…

js页面自适应屏幕大小_移动端自适应布局方法的calc()与vw

前端人员在处理移动端自适应布局时&#xff0c;目前前端最流行的方法应该就是使用媒体查询&#xff0c;来设置HTML的字体大小&#xff0c;然后用rem为单位对Dom的宽高进行设置&#xff0c;这个方法的优势在于兼容性方面很好&#xff0c;劣势则在于当前市场上不同的机型太多&…

C语言深度剖析书籍学习记录 第二章 符号

\ 连接符号&#xff0c;// \ 可以把下一行也注释调编译器 删除注释时&#xff0c;会使用空格进行替代

详细描述三个适于瀑布模型的项目_IT项目管理笔记——方法选择和软件评估

一、管理需求为什么要管理需求&#xff1f;避免失败&#xff0c;提高项目的成功率和需求管理所带来的其他好处软件生命周期中&#xff0c;一个错误发现得越晚&#xff0c;修复错误的费用越高许多错误是潜伏的&#xff0c;并且在错误产生后很长一段时间才被检查出来在需求阶段&a…

Socket通信 客户端加密数据,传递数据密文到服务端,服务端解密密文 输出明文

server // sdf_cpp_warpper.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。 // server端#ifndef UNICODE #define UNICODE #endif#define WIN32_LEAN_AND_MEAN#include <iostream> #include <string> #include <sstream> #include …

主进程中发生了一个javascript错误_知道html5 Web Worker标准吗?能实现JavaScript的多线程?

js为什么是单线程&#xff1f;主要是因为最开始javascript是单纯的服务于浏览器的一种脚步语言(那时候没有nodejs)。浏览器是为了渲染网页&#xff0c;通过dom与用户交互&#xff0c;如果一个线程需要给dom执行click事件&#xff0c;而另一个进程要删除这个dom&#xff0c;这2个…

C语言深度剖析书籍学习记录 第三章 预处理

宏 _LINE_ 表示正在编译的文件的行号_FILE_ 表示正在编译的文件的名字_DATE_ 表示编译时刻的日期字符串&#xff0c;例如: "25 Dec 2007"_TIME_ 表示编译时刻的时间字符串&#xff0c;例如: "12:30:55"_STDC_ 判断该文件是不是定义成标准 C 程序宏名的书写…

js正则限制字符串长度_正则笔记(3)万字长文,慎点。

正则讲了很久&#xff0c;也拖了很久&#xff0c;今天看看怎么用吧&#xff0c;后续更文应该会比较准勤快了。:-)书接上文【正则笔记(2)】。这次我们来看看正则的使用&#xff1a;(注&#xff1a;斜体表示为对应规则写出的正则表达式)一、 常用的正则表达式&#xff1a;1. 验证…

C语言深度剖析书籍学习记录 第四章 指针和数组

p 称为指针变量,p 里存储的内存地址处的内存称为 p 所指向的内存。 指针变量 p 里存储的任何数据都将被当作地址来处理一个基本的数据类型(包括结构体等自定义类型)加上“*” 号就构成了一个指针类型的模子。这个模子的大小是一定的&#xff0c;与“*”号前面的数据类型无 关。…

js中select下拉框重置_如何利用CSS3制作炫酷的下拉框

很多小伙伴都不清楚CSS3是做什么&#xff1f;用途是什么&#xff1f;接下来我就给展示一个css3制作一个炫酷下拉框。其实不只是这些&#xff0c;还有很多。CSS3是CSS(层叠样式表)技术的升级版本&#xff0c;于1999年开始制订&#xff0c;2001年5月23日W3C完成了CSS3的工作草案&…

select选择框必输校验_轮子这么多,我们为什么选择自研NewSQL

作者介绍李鑫&#xff0c;滴滴资深软件开发工程师&#xff0c;多年分布式存储领域设计及开发经验。曾参与NoSQL/NewSQL数据库Fusion、分布式时序数据库sentry、NewSQL数据库SDB等系统的设计开发工作。一、背景Fusion-NewSQL是由滴滴自研的在分布式KV存储基础上构建的NewSQL存储…

C语言深度剖析书籍学习记录 第五章 内存管理

常见的内存错误 定义了指针变量&#xff0c;但是没有为指针分配内存&#xff0c;即指针没有指向一块合法的内存。 结构体成员指针未初始化 很多初学者犯了这个错误还不知道是怎么回事。这里定义了结构体变量 stu&#xff0c;但是他没 想到这个结构体内部 char *name 这成员在定…

怎么改电脑网络ip地址_抛弃重启路由器获取ip地址方式,巧妙运用ip代理改IP工具...

网络是简单的也是复杂的&#xff0c;在如此庞大的网络世界里有太多的不确定因素&#xff0c;导致我们遇到IP限制问题&#xff0c;从而影响到我们的网络访问&#xff0c;而大家都知道&#xff0c;如果遇到ip被限制的问题&#xff0c;最快速直接的办法就是把被限制的ip更换一个新…

C语言深度剖析书籍学习记录 第六章 函数

函数的好处 1、降低复杂性:使用函数的最首要原因是为了降低程序的复杂性&#xff0c;可以使用函数来隐含信息&#xff0c;从而使你不必再考虑这些信息。2、避免重复代码段:如果在两个不同函数中的代码很相似&#xff0c;这往往意味着分解工作有误。这时&#xff0c;应该把两个…

如何把word分装到两个byte_如何核对两个Word文档的内容差别?同事加班半小时,我只花了30秒...

昨天下班前&#xff0c;老板突然发了两份Word文档过来&#xff0c;一份是原稿&#xff0c;还有一份是修订稿&#xff0c;叫我们找出两份文档的内容差别之处&#xff0c;我只花了30秒就搞定了&#xff0c;然后准时下班&#xff01;你想知道我是怎么操作的吗&#xff1f;下面小源…

stm32f767中文手册_ALIENTEK 阿波罗 STM32F767 开发板资料连载第五章 SYSTEM 文件夹

1)实验平台&#xff1a;alientek 阿波罗 STM32F767 开发板2)摘自《STM32F7 开发指南(HAL 库版)》关注官方微信号公众号&#xff0c;获取更多资料&#xff1a;正点原子第五章 SYSTEM 文件夹介绍第三章&#xff0c;我们介绍了如何在 MDK5 下建立 STM32F7 工程。在这个新建的工程之…

手机安卓学习 内核开发

官网开源代码 Documentation - MiCode/Xiaomi_Kernel_OpenSource - Sourcegraph Xiaomi 11T Pro GitHub - MiCode/Xiaomi_Kernel_OpenSource: Xiaomi Mobile Phone Kernel OpenSourceAndroid 开源项目 | Android Open Source Project google安卓官网 目录概览 参考…

vs 启动调用的目标发生异常_如何解决不可测、异常场景的问题?

阿里QA导读&#xff1a;在软件研发过程中&#xff0c;发布前跨多个系统的联调测试是不可或缺的一环&#xff0c;而在联调过程中&#xff0c;经常会遇到一些比较棘手的困难&#xff0c;阻塞整个联调进程。其中比较典型的有&#xff1a;第三方的研发节奏不一致&#xff0c;导致无…