1.基于TCP的简单套接字服务器实现
目录
1. TCP通信流程
2. 服务器端的通信流程
2.1 创建用于监听的套接字
2.2 绑定本地IP地址和端口
2.3 设置监听
2.4 等待接受客户端的连接请求
2.5 与客户端进行通信
2.6 客户端连接服务器
3.代码实现
client.cpp
server.cpp
运行方式
在本文中,我们将深入了解套接字(socket)及其在网络通信中的应用,特别是如何在服务器端创建一个基于TCP的简单通信框架。套接字是程序员进行网络通信的一组接口,主要分为客户端和服务器端。在这篇文章中,我们将重点关注服务器端的实现。
1. TCP通信流程
TCP(传输控制协议)是一个面向连接、安全可靠的流式传输协议,它位于传输层,确保数据的准确传输。
2. 服务器端的通信流程
下面是整个服务器端的通信流程:
2.1 创建用于监听的套接字
首先,我们需要创建一个套接字来监听客户端的连接请求。代码示例如下:
// 创建一个套接字,函数原型
int socket(int domain, int type, int protocol);// 使用
int fd = socket(AF_INET, SOCK_STREAM, 0);
包含的头文件: #include <sys/socket.h>
参数说明:
domain
:地址族协议(如AF_INET
表示使用IPv4,AF_INET6
表示使用IPv6)type
:数据传输协议(SOCK_STREAM
表示TCP,SOCK_DGRAM
表示UDP)protocol
:一般设为0,表示使用默认协议
返回值: 成功返回可用于套接字通信的文件描述符,失败返回 -1。
2.2 绑定本地IP地址和端口
接下来,我们将文件描述符与本地IP地址和端口进行绑定。
// 函数原型
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);// 使用
struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(10000);
addr.sin_addr.s_addr = htonl(INADDR_ANY);int ret = bind(fd, (struct sockaddr*)&addr, sizeof(addr));
参数说明:
sockfd
:监听的文件描述符addr
:要绑定的IP和端口信息addrlen
:addr
指向的内存大小(sizeof(struct sockaddr)
)
返回值: 成功返回0,失败返回 -1。
2.3 设置监听
绑定后,接下来需要设置监听。
// 函数原型
int listen(int sockfd, int backlog);// 使用
int ret = listen(fd, 128);
参数说明:
sockfd
:之前绑定的文件描述符backlog
:指定最大连接请求数
返回值: 成功返回0,失败返回 -1。
2.4 等待接受客户端的连接请求
现在我们需要等待并接受客户端的连接请求。
// 函数原型
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);// 使用
struct sockaddr caddr;
memset(&caddr, 0, sizeof(caddr));
socklen_t len = sizeof(caddr);
int cfd = accept(fd, (struct sockaddr*)&caddr, &len);
参数说明:
sockfd
:之前创建的文件描述符addr
:传出参数,存储客户端的地址信息addrlen
:传出参数,存储地址大小
返回值: 成功返回一个文件描述符,用于与客户端通信,失败返回 -1。注意,这个函数是阻塞的,直到有新的连接请求到来。
2.5 与客户端进行通信
接下来,可以通过read
和write
函数与客户端进行通信。
接收数据:
ssize_t read(int sockfd, void *buf, size_t size);
// 使用
char buf[1024] = {0};
int len = read(cfd, buf, sizeof(buf));
发送数据:
ssize_t write(int fd, const void *buf, size_t len);
// 使用
char msg[] = "Hello, Client!";
int size = write(cfd, msg, strlen(msg));
返回值说明:
- 接收数据(
read
):成功时返回接收到的字节数,连接断开返回0,失败返回-1。 - 发送数据(
write
):成功返回实际发送的字节数,失败返回-1。
2.6 客户端连接服务器
客户端时使用connect()
函数连接服务器,代码示例如下:
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);// 使用
struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(10000);
inet_pton(AF_INET, "1.1.1.1", &addr.sin_addr.s_addr); // 服务器IP地址int ret = connect(fd, (struct sockaddr*)&addr, sizeof(addr));
3.代码实现
server.cpp
#include <stdlib.h> // 提供exit函数
#include <stdio.h> // 提供printf和perror函数
#include <unistd.h> // 提供close函数
#include <arpa/inet.h> // 提供socket、bind、listen、accept等函数
#include <string.h> // 提供memset函数int main()
{// 1. 创建用于监听的套接字int fd = socket(AF_INET, SOCK_STREAM, 0);if (fd == -1) {perror("socket"); // 输出错误信息exit(1); // 退出程序}// 2. 绑定IP地址和端口struct sockaddr_in saddr;memset(&saddr, 0, sizeof(saddr)); // 清空结构体saddr.sin_family = AF_INET; // 使用IPv4saddr.sin_port = htons(10000); // 监听端口,使用网络字节序saddr.sin_addr.s_addr = INADDR_ANY; // 绑定到所有可用的接口int ret = bind(fd, (struct sockaddr*)&saddr, sizeof(saddr));if (ret == -1) {perror("bind"); // 输出错误信息exit(1); // 退出程序}// 3. 设置监听ret = listen(fd, 128); // 监听套接字,最大连接请求数为128if (ret == -1) {perror("listen"); // 输出错误信息exit(1); // 退出程序}// 4. 等待并接受客户端的连接struct sockaddr_in cliaddr; // 保存客户端的地址信息socklen_t len = sizeof(cliaddr); // 地址结构体的大小int cfd = accept(fd, (struct sockaddr*)&cliaddr, &len); // 阻塞等待连接if (cfd == -1) {perror("accept"); // 输出错误信息exit(1); // 退出程序}// 打印新连接的客户端信息char ip[64] = { 0 };printf("new client fd:%d ip:%s, port:%d\n", cfd,inet_ntop(AF_INET, &cliaddr.sin_addr.s_addr, ip, sizeof(ip)), // 获取客户端IPntohs(cliaddr.sin_port)); // 获取客户端端口// 5. 与客户端进行通信char buf[512];while (1) {memset(buf, 0, sizeof(buf)); // 清空缓冲区int len = read(cfd, buf, sizeof(buf)); // 从客户端读取数据if (len > 0) { // 成功接收到数据printf("client says: %s\n", buf); // 打印客户端发送的消息write(cfd, buf, len); // 将相同的数据回发给客户端}else if (len == 0) { // 客户端关闭了连接printf("client is disconnect..\n");break; // 退出循环}else { // 读取失败perror("read"); // 输出错误信息break; // 退出循环}}close(fd); // 关闭监听套接字close(cfd); // 关闭客户端连接套接字return 0; // 程序结束
}
client.cpp
#include <stdlib.h> // 提供exit函数
#include <stdio.h> // 提供printf和perror函数
#include <unistd.h> // 提供close函数
#include <arpa/inet.h> // 提供socket、connect等函数
#include <string.h> // 提供memset和strlen函数int main()
{// 1. 创建套接字用于连接服务器int fd = socket(AF_INET, SOCK_STREAM, 0);if (fd == -1) {perror("socket"); // 输出错误信息exit(1); // 退出程序}// 2. 定义服务器地址和端口struct sockaddr_in saddr; // 创建一个结构体用于存储服务器地址memset(&saddr, 0, sizeof(saddr)); // 清空该结构体saddr.sin_family = AF_INET; // 使用IPv4地址saddr.sin_port = htons(10000); // 设置监听端口,使用网络字节序inet_pton(AF_INET, "127.0.0.1", &saddr.sin_addr.s_addr); // 设置服务器IP地址为localhost// 3. 连接服务器int ret = connect(fd, (struct sockaddr*)&saddr, sizeof(saddr));if (ret == -1) {perror("connect"); // 输出错误信息exit(1); // 退出程序}// 4. 与服务器进行通信int n = 0; // 计数器while (1){// 发送数据char buf[512] = { 0 }; // 初始化缓冲区sprintf(buf, "hi, I am client...%d\n", n++); // 格式化字符串write(fd, buf, strlen(buf)); // 发送数据到服务器// 接收服务器反馈memset(buf, 0, sizeof(buf)); // 清空缓冲区int len = read(fd, buf, sizeof(buf)); // 从服务器读取数据if (len > 0) // 成功接收到数据{printf("server say: %s\n", buf); // 打印服务器返回的数据}else if (len == 0) // 服务器关闭了连接{printf("server disconnect...\n");break; // 退出循环}else // 读取失败{perror("read"); // 输出错误信息break; // 退出循环}sleep(1); // 每隔1秒发送一条数据}close(fd); // 关闭套接字return 0; // 程序结束
}
运行方式
-
编译代码: 在终端中使用
g++
编译器编译client.cpp
和server.cpp
。假设在同一目录下,输入以下命令:g++ server.cpp -o server g++ client.cpp -o client
-
运行服务器: 首先打开一个终端,运行服务器程序:
./server
-
运行客户端: 然后打开另一个终端,运行客户端程序:
./client
-
观察输出: 客户端将每隔一秒发送一条消息,服务器将在终端显示接收到的消息,并回发给客户端。您可以观察客户端和服务器的输出信息。
-
结束运行: 在客户端和服务器之间的通信完成后,可以在客户端终端按
Ctrl+C
结束客户端,服务器将自动检测到客户端的断开并输出相应消息。
相关文章:
1.基于TCP的简单套接字服务器实现
目录 1. TCP通信流程 2. 服务器端的通信流程 2.1 创建用于监听的套接字 2.2 绑定本地IP地址和端口 2.3 设置监听 2.4 等待接受客户端的连接请求 2.5 与客户端进行通信 2.6 客户端连接服务器 3.代码实现 client.cpp server.cpp 运行方式 在本文中,我们将…...
MantisBT在Windows10上安装部署详细步骤
MantisBT 是一款基于 Web 的开源缺陷跟踪系统,以下是在 Windows 10 上安装部署 MantisBT 的详细步骤: 1. 安装必要的环境 MantisBT 是一个基于 PHP 的 Web 应用程序,因此需要安装 Web 服务器(如 Apache)、PHP 和数据…...
zookeepernacoskafka之间的联系
一、ZooKeeper与Kafka的协同工作原理 1. 核心关系:Kafka对ZooKeeper的依赖 在Kafka 2.8版本之前,ZooKeeper是Kafka集群的“大脑”,负责管理集群元数据、协调节点状态和故障恢复。两者的协同主要通过以下关键机制实现: Broker注册…...
【QT】 布局器
参考博客:https://blog.csdn.net/Fdog_/article/details/107522283 目录 布局管理器概念常见的布局管理器及特点🔵QHBoxLayout水平布局🔵QVBoxLayout垂直布局 🔵QGridLayout网格布局 🔵QFormLayout表单布局 QT 高级布…...
力扣45.跳跃游戏
45. 跳跃游戏 II - 力扣(LeetCode) 代码区: #include<vector> class Solution {public:int jump(vector<int>& nums) {int ans[10005] ;memset(ans,1e4,sizeof(ans));ans[0]0;for(int i0;i<nums.size();i){for(int j1;j…...
【蓝桥杯】真题 路径(数论+dp)
思路 求最小公倍数LCM问题很好求,这里看似是求图最短路径,实际上由于只有[i,i21]之间存在路径,所以用线性dp效率更高,当然用bfs,dijstra,floyed也可,毕竟是填空题。 code def gcd(a,b):if a …...
敏捷需求分析之INVEST原则
INVEST原则是什么 INVEST 是用户故事的六个核心标准,由敏捷教练 Bill Wake 提出,用于确保用户故事具备可执行性和价值导向性。 1. I - Independent(独立的) 含义:用户故事应独立于其他故事,避免依赖关系。问题:若故事 A 必须等待故事 B 完成才能开发,会导致进度阻塞。…...
Apache Flink技术原理深入解析:任务执行流程全景图
前言 本文隶属于专栏《大数据技术体系》,该专栏为笔者原创,引用请注明来源,不足和错误之处请在评论区帮忙指出,谢谢! 本专栏目录结构和参考文献请见大数据技术体系 思维导图 📌 引言 Apache Flink 作为一款高性能的分布式流处理引擎,其内部执行机制精妙而复杂。本文将…...
UE5小石子阴影在非常近距离才显示的问题
Unreal中采用LandscapeGrass生成的地形,在MovieRenderQueue中渲染时阴影显示距离有问题,在很近的时候才会有影子,怎么解决? 地面上通过grass生成的小石子的阴影只能在很近的时候才能显示出来,需要如下调整 r.Shadow.R…...
WebAssembly实践,性能也有局限性
个人博客原文地址 WebAssembly(简称 wasm) 是一种旨在突破 Web 性能瓶颈的技术方案。它由 W3C 官方推动,并且得到了主流浏览器的广泛支持。它的核心思想是通过运行其他高性能编程语言(比如 C、C、Rust 等)来实现复杂功…...
第一天学爬虫
阅读提示:我今天才开始尝试爬虫,写的不好请见谅。 一、准备工具 requests库:发送HTTP请求并获取网页内容。BeautifulSoup库:解析HTML页面并提取数据。pandas库:保存抓取到的数据到CSV文件中。 二、爬取步骤 发送请求…...
【FAQ】HarmonyOS SDK 闭源开放能力 —Push Kit(11)
1.问题描述: 鸿蒙push右侧图表没有正常展示。 解决方案: .jpg格式文件,头信息必须是这个“jpg:ffd8”。 2.问题描述: 安卓端App在开发者平台申请了Android应用的通知消息自分类权益,鸿蒙应用的自分类权…...
Spring WebSecurityCustomizer 的作用
Spring WebSecurityCustomizer 是 Spring Security 框架中用来 自定义 Web 安全配置 的一个接口。 它的主要作用是在开发中我们能够 精细的控制哪些请求会被 Spring Security 完全忽略,不进行任何安全检查和过滤。 我们可以把它想象成是 Spring Security 大门上的一…...
uniapp动态循环表单校验失败:初始值校验
问题现象 💥 在实现动态增减的单价输入表单时(基于uv-form组件),遇到以下诡异现象: <uv-input>的v-model绑定初始值为数字类型时,required规则失效 ❌数字类型与字符串类型校验表现不一致 🔢技术栈背景 🛠️ 框架:Vue3 + uni-appUI库:uv-ui校验方案:计算属…...
线性代数核心概念与NumPy科学计算实战全解析
前言 学习方法: 思维导图,梳理 多记忆,函数名和功能,参数 学会应用,不要钻牛角尖 一、浅解线性代数 1.1标量 标量是一个只有大小没有方向的量。在数学上,标量通常表示为一个普通的数字,如质量…...
如何理解 Apache Iceberg 与湖仓一体(Lakehouse)?
一、什么是湖仓一体(Lakehouse)? 湖仓一体是一种融合了数据湖的灵活存储能力与数据仓库的高效分析功能的现代数据架构。它通过整合两者的优势,解决了传统架构的局限性,为企业数据处理提供了更全面的解决方案。 数据湖…...
若依框架二次开发——若依集成 JSEncrypt 实现密码加密传输方式
文章目录 一、问题场景二、相关技术介绍1. RSA 加密算法2. JSEncrypt三、实现步骤1. 前端加密处理2. 后端解密处理3. 登录逻辑处理四、测试流程1. 前端测试2. 后端测试3. 运行效果五、总结一、问题场景 在 RuoYi 系统中,默认情况下,用户在登录时会将明文密码直接传输到服务器…...
Rust Web 开发新选择:探索 Hyperlane 轻量级 HTTP 服务器框架
Rust Web 开发新选择:探索 Hyperlane 轻量级 HTTP 服务器框架 在 Web 开发领域,Rust 以其高性能和内存安全性逐渐受到关注。而在众多 Web 框架中,hyperlane 作为一款轻量级、高性能的 HTTP 服务器框架,正悄然成为 Rust 生态中的明…...
初识 模版 和 STL
前言 今天简单和大家分享一下C重要的两个内容,经过之前的学习我们已经了解了C的大致语法,接下来就是C相关的库和一些操作了,他们能极大地缩小我们C语言阶段的代码量,让写代码变得轻松起来。 1.关于模版 <1>泛型编程 我们学…...
加新题了,MySQL 8.0 OCP 认证考试 题库更新
MySQL 8.0 OCP 认证考试 题库更新 MySQL 8.0 Database Administrator 考试科目:1Z0-908 近期发现,MySQL OCP认证考试题库发生变化,出现了很多新题,对此,CUUG专门收集整理了最新版本的MySQL考试原题,并会给…...
26考研——树与二叉树_树、森林(5)
408答疑 文章目录 二、树、森林树的基本概念树的定义和特性树的定义树的特性 基本术语树的基本术语和概念祖先、子孙、双亲、孩子、兄弟和堂兄弟结点的层次、度、深度和高度树的度和高度分支结点和叶结点有序树和无序树路径和路径长度 森林的基本术语和概念森林的定义森林与树的…...
26考研——图_图的基本概念(6)
408答疑 文章目录 一、图的基本概念图的定义非空性非线性结构 顶点和边的表示顶点边 有向图 & 无向图有向图有向图 G 1 G_1 G1 的表示 无向图无向图 G 2 G_2 G2 的表示 简单图 & 多重图简单图多重图 顶点的度、入度和出度顶点的度有向图的度 路径、路径长度和回路…...
笔试面试01 c/c++
基础知识 什么是数据结构?请简要描述常见的数据结构类型。 数据结构是组织和存储数据的方式,以便于高效访问和修改。常见的数据结构包括: 数组:固定大小的线性数据结构,支持随机访问。 链表:由节点组成的线…...
2025清华大学:DeepSeek教程全集(PDF+视频精讲,共10份).zip
一、资料列表 第一课:Deepseek基础入门 第二课:DeepSeek赋能职场 第三课:普通人如何抓住DeepSeek红利 第四课:让科研像聊天一样简单 第五课:DeepSeek与AI幻觉 第六课:基于DeepSeek的AI音乐词曲的创造法 第…...
消息队列(Kafka及RocketMQ等对比联系)
目录 消息队列 一、为什么使用消息队列?消息队列有什么优点/缺点?介绍下Kafka、ActiveMQ、RabbitMQ、RocketMQ有什么优点缺点,如何取舍? 1.公司业务场景是什么,这个业务场景有什么挑战,如果不用MQ有什么麻…...
Go 语言 fmt 模块的完整方法详解及示例
以下是 Go 语言 fmt 模块的完整方法详解及示例,涵盖所有核心功能: 一、输出函数 将数据写入标准输出、文件或字符串。 1. Print / Println / Printf 功能 Print: 写入标准输出,不换行。Println: 写入标准输出并换行。Printf: 格式化写入标…...
Centos 7 安装VNC服务
Centos 7 安装VNC服务 1. 安装 TigerVNC2. 设置 VNC 密码3. 创建并配置 x0vncserver 服务4. 启用并启动服务5. 检查服务状态6. 配置防火墙7. 连接 VNC问题1:出现无法安装可能是镜像源导致的。手动配置镜像源清除 YUM 缓存并重新加载 1. 安装 TigerVNC 确保已安装 TigerVNC 服务…...
3.25-3 request断言
一.request断言 if断言 案例: import requests srequests.Session() url1"http://49.233.201.254:8080/cms/manage/loginJump.do" data1{userAccount:admin,loginPwd:123456} h1{"Content-Type":"application/x-www-form-urlencoded&…...
cmakelist中添加opencv
版本选择 qt的msvc,版本2019 opencv版本 4.5.3 配置了环境变量 x64下的v14中的bin 配置头文件 {"configurations": [{"name": "Win32","includePath": ["${workspaceFolder}","d:\\QT\\6.5.3\\msvc20…...
【003安卓开发方案调研】之ReactNative技术开发安卓
基于2025年最新行业动态和搜索资料,以下是针对国内使用React Native(RN)开发安卓应用的深度分析: 一、技术成熟度评估 1. 核心架构升级 新架构全面普及:2024年起,React Native的 新架构(Fabri…...
面试中如何回答性能优化的问题
性能问题和Bug不同,后者的分析和解决思路更清晰,很多时候从应用日志(文中的应用指分布式服务下的单个节点)即可直接找到问题根源,而性能问题,其排查思路更为复杂一些。 对应用进行性能优化,是一个系统性的工程,对工程师的技术广度和技术深度都有所要求。一个简单的应用…...
使用cursor开发java案例——springboot整合elasticsearch
安装elasticsearch 打开cursor,输入如下提示词 使用springboot整合elasticsearch。其中elasticsearch服务器ip:192.168.236.134 管理员用户名elastic 管理员密码 PdQy_xfR2yLhpok*MK_ 监听端口9200点Accept all 使用idea打开生成的项目 ࿰…...
CCF-CSP认证题目练习及其题解(4
【问题描述】 涛涛最近要负责图书馆的管理工作,需要记录下每天读者的到访情况。每位读者有一个编号,每条记录用读者的编号来表示。给出读者的来访记录,请问每一条记录中的读者是第几次出现。 【输入形式】 输入的第一行包含一个整数n&#x…...
Chrome 134 版本开发者工具(DevTools)更新内容
Chrome 134 版本开发者工具(DevTools)更新内容 一、隐私与安全面板 旧的 Security 面板已演变为隐私与安全面板,并新增了一个专注于隐私的部分。在该部分中,可以: 在 DevTools 打开时,临时限制第三方 Co…...
12届蓝桥杯—货物摆放
货物摆放 题目描述 小蓝有一个超大的仓库,可以摆放很多货物。 现在,小蓝有 nn 箱货物要摆放在仓库,每箱货物都是规则的正方体。小蓝规定了长、宽、高三个互相垂直的方向,每箱货物的边都必须严格平行于长、宽、高。 小蓝希望所…...
oracle查询归档日志使用量
1.统计最近30天的数据 SELECT TRUNC(first_time, DD) "日期", SUM(blocks * block_size) / 1024 / 1024 / 1024 "大小(GB)" FROM v$archived_log WHERE first_time > SYSDATE - 30 -- 统计最近30天的数据 GROUP BY TRUNC(first_time, DD) ORDER BY 1 D…...
Redis 发布订阅
Redis 发布订阅 概述 Redis 发布订阅(Pub/Sub)是一种消息传递模式,允许应用在多个客户端之间进行通信。在Redis中,发布订阅允许客户端订阅一个或多个频道,并在这些频道上发布消息。其他订阅了相同频道的客户端会接收到这些消息。 核心概念 频道(Channels) 频道是发…...
歌曲缓存相关功能
1. 核心组件 MusicCacheManager (音乐缓存管理器) 单例模式:确保全局只有一个实例,方便管理。 private static var instance: MusicCacheManager?static func shared() -> MusicCacheManager {if instance nil {instance MusicCacheManager()}ret…...
MySQL学习之用户管理
MySQL学习之用户管理 一、用户1、用户信息2、创建用户3、修改用户密码4、删除用户 二、数据库权限1、MySQL中的权限2、给用户授权3、回收权限 一、用户 1、用户信息 MySQL用户管理: ①、与Linux操作系统类似,MySQL中也有超级用户和普通用户之分。 ②、如…...
【第十三届“泰迪杯”数据挖掘挑战赛】【2025泰迪杯】A题解题全流程(持续更新)
【第十三届“泰迪杯”数据挖掘挑战赛】【2025泰迪杯】A题解题全流程-思路(持续更新) 写在前面: 1、A题、C题将会持续更新,陆续更新发布文章 2、赛题交流咨询Q群:1037590285 3、全家桶依旧包含: 代码、…...
算法训练营第二十三天 | 贪心算法(一)
文章目录 一、贪心算法理论基础二、Leetcode 455.分发饼干二、Leetcode 376. 摆动序列三、Leetcode 53. 最大子序和 一、贪心算法理论基础 贪心算法是一种在每一步选择中都采取当前状态下的最优决策,从而希望最终达到全局最优解的算法设计技术。 基本思想 贪心算…...
SpringCloud消息总线:Bus事件广播与配置动态刷新
文章目录 引言一、Spring Cloud Bus基本架构二、配置动态刷新实现2.1 基础配置2.2 刷新流程2.3 定向刷新 三、自定义事件广播3.1 定义自定义事件3.2 注册和监听事件3.3 发布事件 四、高级配置与优化4.1 消息持久化4.2 事件追踪4.3 安全控制 总结 引言 在微服务架构中ÿ…...
家庭网络结构之局域网通信
整个互联网非常复杂,涉及到很多知识,学习互联网不能一蹴而就,所以这里从最简单的家庭网络开始学习 家庭网络一般是通过Modem( 作用:进行数字信号和模拟信号的转换 ) 拨号上网,然后通过家庭路由器,将网络连接…...
突破反爬困境:SDK架构设计,为什么选择独立服务模式(四)
声明 本文所讨论的内容及技术均纯属学术交流与技术研究目的,旨在探讨和总结互联网数据流动、前后端技术架构及安全防御中的技术演进。文中提及的各类技术手段和策略均仅供技术人员在合法与合规的前提下进行研究、学习与防御测试之用。 作者不支持亦不鼓励任何未经授…...
java 设置操作系统编码、jvm平台编码和日志文件编码都为UTF-8的操作方式
以下是 Java中设置操作系统编码、JVM平台编码和日志文件编码为UTF-8 的详细步骤和代码示例: 一、设置操作系统编码为UTF-8 1. Windows系统 修改系统区域设置: 进入 控制面板 → 时钟和区域 → 区域。在“管理”选项卡中,点击“更改系统区域…...
SpringBoot:几种常用的接口日期格式化方法
全局时间格式化 通过在配置文件中设置可以实现全局时间格式化。在 Spring Boot 的配置文件 application.properties(或 application.yml)中添加以下两行配置: #?格式化全局时间字段 spring.jackson.date-formatyyyy-MM-dd?HH:mm:ss #?指…...
解题思路:LeetCode 2711. 对角线上不同值的数量差
解题思路:LeetCode 2711. 对角线上不同值的数量差 在LeetCode的题目2711中,我们需要计算一个矩阵中每个单元格的左上角对角线和右下角对角线上不同值的数量差。这个问题可以通过暴力法解决,但效率较低。本文将介绍一种更高效的解决方案&…...
Jackson实现JSON数据的合并
JSON数据的操作,系列文章: 《Jackson的核心类与API方法:ObjectMapper、JsonNode、ObjectNode、ArrayNode》 《Jackson的使用与创建Jackson工具类》 《Jackson使用ObjectNode对象实现JSON对象数据(一):增、删…...
Elasticsearch 倒排索引 和 正排索引
一、倒排索引 倒排索引是 Elasticsearch 实现高效全文搜索的核心技术。它通过将词项与文档 ID 关联,支持快速检索、短语查询、布尔查询和相关性评分。尽管倒排索引在存储和更新方面有一定的开销,但通过词典优化、倒排列表压缩、分片和缓存等技术&#x…...
Cocos Creator Shader入门实战(五):材质的了解、使用和动态构建
引擎:3.8.5 您好,我是鹤九日! 回顾 前面的几篇文章,讲述的主要是Cocos引擎对Shader使用的一些固定规则,这里汇总下: 一、Shader实现基础是OpenGL ES可编程渲染管线,开发者只需关注顶点着色器和…...