如何写一篇基于Spring Boot + Vue + 微信小程序的软件的接口文档
如何写一篇基于Spring Boot + Vue + 微信小程序的软件的接口文档
下面是一个例子,仅供参考!
基于Spring Boot + Vue + 微信小程序的博客系统接口文档
技术栈:Spring Boot 3.x + Vue 3 + Element Plus + 微信小程序原生框架
文档版本:v1.5
最后更新:2025年6月8日
目录
- 1. 项目概述
- 2. 技术架构图
- 3. 开发环境配置
- 4. 数据库设计
- 5. 接口规范
- 6. 用户模块接口
- 7. 博客模块接口
- 8. 评论模块接口
- 9. 文件服务接口
- 10. 微信小程序接口
- 11. 安全与鉴权
- 12. 错误代码表
- 13. 接口测试方案
- 14. 性能优化建议
- 15. 部署方案
1. 项目概述
本系统是一个完整的博客平台解决方案,包含:
- 后台服务:基于Spring Boot 3.x构建的RESTful API服务
- 管理后台:基于Vue 3 + Element Plus的管理系统
- 微信小程序:面向终端用户的移动端应用
核心功能模块:
├── 用户中心
│ ├── 微信授权登录
│ ├── 手机号注册
│ ├── 用户信息管理
│ └── 权限控制
├── 博客管理
│ ├── 博客发布/编辑
│ ├── 富文本编辑器
│ ├── 博客分类/标签
│ └── 推荐算法
├── 互动系统
│ ├── 评论/回复
│ ├── 点赞/收藏
│ └── 消息通知
├── 文件服务
│ ├── 图片上传
│ ├── 文件存储
│ └── CDN加速
└── 数据分析├── 访问统计├── 热门排行└── 用户行为分析
2. 技术架构图
3. 开发环境配置
3.1 后端环境
# JDK版本
openjdk 17.0.8# 主要依赖
dependencies {implementation 'org.springframework.boot:spring-boot-starter-web'implementation 'org.springframework.boot:spring-boot-starter-data-jpa'implementation 'org.springframework.boot:spring-boot-starter-security'implementation 'com.auth0:java-jwt:4.4.0'implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.2.0'implementation 'com.tencentcloudapi:tencentcloud-sdk-java:3.1.947'
}
3.2 前端环境
# Vue管理后台
Node.js v18.16.0
Vue 3.3.4
Element Plus 2.3.14# 微信小程序
微信开发者工具 1.06.2303220
3.3 数据库配置
spring:datasource:url: jdbc:mysql://localhost:3306/blog_db?useSSL=false&characterEncoding=utf8username: rootpassword: yourpassworddriver-class-name: com.mysql.cj.jdbc.Driverjpa:hibernate:ddl-auto: updateshow-sql: true
4. 数据库设计
4.1 核心表结构
用户表 (user)
字段 | 类型 | 描述 |
---|---|---|
id | BIGINT | 主键 |
openid | VARCHAR(128) | 微信openid |
nickname | VARCHAR(64) | 昵称 |
avatar | VARCHAR(255) | 头像URL |
phone | VARCHAR(20) | 手机号 |
create_time | DATETIME | 创建时间 |
博客表 (blog)
字段 | 类型 | 描述 |
---|---|---|
id | BIGINT | 主键 |
title | VARCHAR(255) | 标题 |
content | LONGTEXT | 内容 |
author_id | BIGINT | 作者ID |
category_id | INT | 分类ID |
status | TINYINT | 状态(0-草稿,1-已发布) |
view_count | INT | 浏览量 |
create_time | DATETIME | 创建时间 |
评论表 (comment)
字段 | 类型 | 描述 |
---|---|---|
id | BIGINT | 主键 |
blog_id | BIGINT | 博客ID |
user_id | BIGINT | 用户ID |
content | VARCHAR(500) | 评论内容 |
parent_id | BIGINT | 父评论ID |
create_time | DATETIME | 创建时间 |
5. 接口规范
5.1 请求格式
{"header": {"token": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...","appId": "wx1234567890abcdef"},"body": {"key1": "value1","key2": "value2"}
}
5.2 响应格式
{"code": 200,"message": "操作成功","data": {// 业务数据},"timestamp": 1686234567890
}
5.3 HTTP状态码
状态码 | 说明 |
---|---|
200 OK | 请求成功 |
201 Created | 创建成功 |
400 Bad Request | 请求参数错误 |
401 Unauthorized | 未授权 |
403 Forbidden | 权限不足 |
404 Not Found | 资源不存在 |
500 Internal Server Error | 服务器内部错误 |
6. 用户模块接口
6.1 微信小程序登录
URL:/api/v1/user/wxlogin
方法:POST
请求参数:
{"code": "081qRT000wDk8e1mYq300Q6ZfE0qRT0g"
}
响应示例:
{"code": 200,"message": "登录成功","data": {"userId": 10001,"nickname": "张三","avatar": "https://cdn.example.com/avatar/10001.jpg","token": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."}
}
6.2 获取用户信息
URL:/api/v1/user/info/{userId}
方法:GET
请求头:
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
响应示例:
{"code": 200,"data": {"userId": 10001,"nickname": "张三","avatar": "https://cdn.example.com/avatar/10001.jpg","blogCount": 24,"fansCount": 128,"followCount": 56,"registerDate": "2023-06-01"}
}
7. 博客模块接口
7.1 发布博客
URL:/api/v1/blog/create
方法:POST
请求头:Authorization: Bearer <token>
请求体:
{"title": "Spring Boot最佳实践","content": "<p>Spring Boot是构建Java应用的利器...</p>","categoryId": 2,"tags": ["Java", "后端", "Spring"],"coverImage": "https://cdn.example.com/images/spring-boot.png"
}
响应示例:
{"code": 201,"message": "博客创建成功","data": {"blogId": 100001,"viewUrl": "/blog/100001"}
}
7.2 获取博客详情
URL:/api/v1/blog/{blogId}
方法:GET
请求参数:
// 路径参数
blogId: 100001// 查询参数
?preview=true // 预览模式
响应示例:
{"code": 200,"data": {"blogId": 100001,"title": "Spring Boot最佳实践","content": "<p>Spring Boot是构建Java应用的利器...</p>","author": {"userId": 10001,"nickname": "张三","avatar": "https://cdn.example.com/avatar/10001.jpg"},"viewCount": 1245,"likeCount": 89,"commentCount": 23,"publishTime": "2023-06-08 14:30:00","tags": ["Java", "后端", "Spring"]}
}
8. 评论模块接口
8.1 发表评论
URL:/api/v1/comment/create
方法:POST
请求头:Authorization: Bearer <token>
请求体:
{"blogId": 100001,"content": "这篇文章很有帮助!","parentId": 0 // 0表示顶级评论
}
响应示例:
{"code": 201,"message": "评论发布成功","data": {"commentId": 5001,"createTime": "2023-06-08 15:30:00"}
}
8.2 获取评论列表
URL:/api/v1/comment/list
方法:GET
请求参数:
{"blogId": 100001,"page": 1,"size": 10
}
响应示例:
{"code": 200,"data": {"total": 23,"page": 1,"size": 10,"comments": [{"commentId": 5001,"content": "这篇文章很有帮助!","user": {"userId": 10002,"nickname": "李四","avatar": "https://cdn.example.com/avatar/10002.jpg"},"likeCount": 5,"createTime": "2023-06-08 15:30:00","replies": [{"commentId": 5002,"content": "同感,学到了很多","user": {...},"createTime": "..."}]}]}
}
9. 文件服务接口
9.1 文件上传
URL:/api/v1/file/upload
方法:POST
Content-Type:multipart/form-data
请求参数:
POST /api/v1/file/upload HTTP/1.1
Content-Type: multipart/form-data; boundary=boundary
Authorization: Bearer <token>--boundary
Content-Disposition: form-data; name="file"; filename="example.jpg"
Content-Type: image/jpeg<binary data>
--boundary--
响应示例:
{"code": 200,"data": {"fileUrl": "https://cdn.example.com/upload/2023/06/08/abcdef123456.jpg","fileSize": 245678,"fileType": "image/jpeg"}
}
10. 微信小程序接口
10.1 小程序初始化配置
// app.js
App({globalData: {baseUrl: 'https://api.example.com',userInfo: null},onLaunch() {// 检查登录状态wx.checkSession({success: () => {// session_key 未过期this.loadUserInfo();},fail: () => {// session_key 已过期this.login();}});},login() {wx.login({success: res => {if (res.code) {// 发送code到后端wx.request({url: `${this.globalData.baseUrl}/api/v1/user/wxlogin`,method: 'POST',data: { code: res.code },success: (resp) => {const data = resp.data.data;wx.setStorageSync('token', data.token);this.globalData.userInfo = data;}});}}});}
});
10.2 获取博客列表
// pages/index/index.js
Page({data: {blogs: [],loading: false,page: 1,hasMore: true},onLoad() {this.loadBlogs();},loadBlogs() {if (!this.data.hasMore || this.data.loading) return;this.setData({ loading: true });wx.request({url: `${getApp().globalData.baseUrl}/api/v1/blog/list`,method: 'GET',data: {page: this.data.page,size: 10},header: {'Authorization': wx.getStorageSync('token') || ''},success: (res) => {const data = res.data.data;this.setData({blogs: [...this.data.blogs, ...data.list],page: this.data.page + 1,hasMore: data.hasMore,loading: false});}});}
});
11. 安全与鉴权
11.1 JWT认证流程
11.2 Spring Security配置
@Configuration
@EnableWebSecurity
public class SecurityConfig {@Beanpublic SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {http.csrf().disable().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and().authorizeHttpRequests(auth -> auth.requestMatchers("/api/v1/user/wxlogin").permitAll().requestMatchers("/api/v1/blog/**").permitAll().requestMatchers("/api/v1/file/download/**").permitAll().anyRequest().authenticated()).addFilterBefore(jwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);return http.build();}@Beanpublic JwtAuthenticationFilter jwtAuthenticationFilter() {return new JwtAuthenticationFilter();}
}
12. 错误代码表
错误码 | 说明 | 解决方案 |
---|---|---|
10001 | 无效的token | 重新登录获取新token |
10002 | token已过期 | 刷新token或重新登录 |
20001 | 参数校验失败 | 检查请求参数格式 |
30001 | 博客不存在 | 检查博客ID是否正确 |
40001 | 文件上传失败 | 检查文件格式和大小 |
50001 | 系统内部错误 | 联系管理员 |
13. 接口测试方案
13.1 Postman测试集
{"info": {"name": "Blog API Test","schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"},"item": [{"name": "用户登录","request": {"method": "POST","header": [],"body": {"mode": "raw","raw": "{\"code\":\"test_code_123456\"}"},"url": {"raw": "{{baseUrl}}/api/v1/user/wxlogin","host": ["{{baseUrl}}"]}}},{"name": "创建博客","request": {"method": "POST","header": [{"key": "Authorization","value": "Bearer {{token}}"}],"body": {"mode": "raw","raw": "{\"title\":\"测试博客\",\"content\":\"测试内容\"}"},"url": {"raw": "{{baseUrl}}/api/v1/blog/create","host": ["{{baseUrl}}"]}}}]
}
13.2 JMeter性能测试
测试计划
├── 线程组 (100并发)
│ ├── HTTP请求: 博客列表
│ ├── HTTP请求: 博客详情
│ └── HTTP请求: 发表评论
├── 监听器
│ ├── 聚合报告
│ ├── 响应时间图
│ └── 每秒事务数
14. 性能优化建议
14.1 数据库优化
-- 添加索引
CREATE INDEX idx_blog_author ON blog(author_id);
CREATE INDEX idx_comment_blog ON comment(blog_id);-- 分页优化
SELECT * FROM blog
WHERE status = 1
ORDER BY create_time DESC
LIMIT 10000, 20; -- 避免深分页-- 改为
SELECT * FROM blog
WHERE id < (SELECT id FROM blog ORDER BY id DESC LIMIT 10000, 1)
ORDER BY id DESC
LIMIT 20;
14.2 缓存策略
// Redis缓存示例
@Service
public class BlogServiceImpl implements BlogService {private final String CACHE_PREFIX = "blog:";@Cacheable(value = "blogCache", key = "#blogId")public Blog getBlogById(Long blogId) {return blogRepository.findById(blogId).orElse(null);}@CacheEvict(value = "blogCache", key = "#blogId")public void updateBlog(Long blogId, Blog blog) {// 更新逻辑}
}
15. 部署方案
15.1 Docker部署配置
# Dockerfile
FROM openjdk:17-jdk-slim
VOLUME /tmp
COPY target/blog-api-1.0.0.jar app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
# docker-compose.yml
version: '3.8'
services:app:image: blog-api:1.0.0container_name: blog-apiports:- "8080:8080"environment:SPRING_DATASOURCE_URL: jdbc:mysql://mysql:3306/blog_dbSPRING_REDIS_HOST: redisdepends_on:- mysql- redismysql:image: mysql:8.0environment:MYSQL_ROOT_PASSWORD: rootpassMYSQL_DATABASE: blog_dbvolumes:- mysql-data:/var/lib/mysqlredis:image: redis:6.2-alpinevolumes:mysql-data:
15.2 Nginx配置
server {listen 80;server_name api.example.com;location / {proxy_pass http://127.0.0.1:8080;proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;# WebSocket支持proxy_http_version 1.1;proxy_set_header Upgrade $http_upgrade;proxy_set_header Connection "upgrade";}# 静态资源缓存location ~* \.(jpg|jpeg|png|gif|css|js)$ {expires 30d;add_header Cache-Control "public, no-transform";}
}
文档说明:
- 本文涵盖系统所有核心接口
- 接口持续更新中,请关注GitHub仓库获取最新版本
- 实际开发中请结合Swagger文档使用:
http://localhost:8080/swagger-ui/index.html
温馨提示:本文档仅作为开发参考,实际接口实现可能因业务需求调整。建议使用Postman等工具进行接口测试,确保功能正常后再进行客户端集成。
相关文章:
如何写一篇基于Spring Boot + Vue + 微信小程序的软件的接口文档
如何写一篇基于Spring Boot Vue 微信小程序的软件的接口文档 下面是一个例子,仅供参考! 基于Spring Boot Vue 微信小程序的博客系统接口文档 技术栈:Spring Boot 3.x Vue 3 Element Plus 微信小程序原生框架 文档版本:v1…...
上位机知识篇---网页端实现
一、网页端基础概念 网页的本质 网页是通过浏览器展示的超文本(HTML)内容,依赖 HTTP/HTTPS 协议 进行数据传输。组成要素: 结构层(HTML):定义页面内容和语义(如标题、段落、列表等&a…...
鼠标的拖动效果
1、变量的设置 let isDragging false; let startX; let startY; let endX; let endY; let box null;isDragging : 表示是否推拽startX、startY:表示起始坐标,相对于元素endX、endY:表示结束坐标,相对于元素box&…...

第四讲:类和对象(下)
1. 再探构造函数 • 之前我们实现构造函数时,初始化成员变量主要使⽤函数体内赋值,构造函数初始化还有⼀种⽅ 式,就是初始化列表,初始化列表的使⽤⽅式是以⼀个冒号开始,接着是⼀个以逗号分隔的数据成 员列表ÿ…...
C++ vector容器存储对象和存储指针的区别(vector对象、vector指针)(存储指针时推荐使用智能指针)
文章目录 **1. 内存管理**- **存储对象**:- **存储指针**: **2. 生命周期控制**- **存储对象**:- **存储指针**: **3. 性能差异**- **存储对象**:- **存储指针**: **4. 使用场景**- **选择存储对象的情况**…...
C#和C++在编译过程中的文件区分
1. .h是头文件(Header File) 用来 声明类、函数、常量等。 通常不包含实际实现,只是“定义接口” // 示例:math_utils.h#pragma once int add(int a, int b); //定义函数名2. .cpp是源文件(Source File&…...

50天50个小项目 (Vue3 + Tailwindcss V4) ✨ | Dad Jokes(冷笑话卡片)
📅 我们继续 50 个小项目挑战!—— DadJokes 组件 仓库地址:https://github.com/SunACong/50-vue-projects 项目预览地址:https://50-vue-projects.vercel.app/ 豆包翻译确实可以,冷笑话应该属于各类语言比较难理解的…...

Spring AOP执行原理源码解析
对【com.example.demo.TestAspect#aopTest】连接点增加了五个通知 在调用【com.example.demo.A#testAop()】(用户自定义)方法时,Cglib拦截器对其进行了拦截 可以看到执行顺序分别是环绕前置,前置,环绕后置,…...

基于FPGA的超声波显示水位距离,通过蓝牙传输水位数据到手机,同时支持RAM存储水位数据,读取数据。
基于FPGA的超声波显示水位距离 前言一、整体框架二、代码架构1.超声波测距模块2.蓝牙数据发送模块3.数码管数据切换模块4.数码管驱动模块6.串口驱动7.顶层模块8.RAM ip核 仿真相关截图 前言 随着工业化进程的加速和环境保护意识的提升,对水资源管理和水位监测的需求…...
使用swoole作为MQTT客户端并接收实现即时消息推送
环境准备 首先需要安装swoole 可以使用pecl进行安装 ,如 pecl install swool, 注意加上版本号 或者使用构建好的docker镜像,这里使用构建好的 zacksleo/php:7.1-alpine-fpm-swoole 镜像 使用 compose 安装依赖库 composer require jesusslim/mqttcl…...

在Windows下利用LoongArch-toolchain交叉编译Qt
文章目录 0.交叉编译的必要性1.下载交叉编译工具链1.1.直接在Windows下使用mingw(不使用虚拟机)编译(还没成功,无法编译)1.2.在虚拟机中的Ubuntu中进行交叉编译 2.下载qt源码3.编译Qt3.1.创建loongarch64的mkspec3.2.创…...
如何在 React 中监听 div 的滚动事件
在 React 中监听 div 的滚动事件(scroll),可以通过为该 div 添加 onScroll 属性来实现。以下是一个基本的例子: ✅ 示例:监听 div 的滚动事件 import React, { useRef } from react;function ScrollComponent() {cons…...

AIRIOT无人机安防解决方案
随着无人机技术的飞速发展和广泛应用,其在安防领域的价值日益凸显,从关键设施巡检、大型活动安保到边境巡防、应急救援,无人机正成为立体化安防体系不可或缺的“空中哨兵”。然而,无人机安防应用蓬勃发展的同时,其自身…...

华为OD机考 - 水仙花数 Ⅰ(2025B卷 100分)
import java.util.*; public static Integer get(int count,int c){if(count<3||count>7){return -1;}//存储每位数的最高位……最低位int[] arr new int[count];List<Integer> res new ArrayList<>();for(int i(int) Math.pow(10,count-1);i<(int) Math…...
软考 系统架构设计师系列知识点之杂项集萃(81)
接前一篇文章:软考 系统架构设计师系列知识点之杂项集萃(80) 第145题 商业智能是企业对商业数据的搜集、管理和分析的系统过程,主要技术包括()。 A. 数据仓库、联机分析和数据挖掘 B. 数据采集、数据清洗…...

php apache构建 Web 服务器
虚拟机配置流程winsever2016配置Apache、Mysql、php_windows server 2016配置web服务器-CSDN博客 PHP 和 Apache 通过 模块化协作 共同构建 Web 服务器,以下是它们的交互机制和工作流程: 一、核心组件分工 组件角色ApacheWeb …...
Ntfs!ReadIndexBuffer函数分析之nt!CcGetVirtualAddress函数之nt!CcGetVacbMiss
第一部分: NtfsMapStream( IrpContext, Scb, LlBytesFromIndexBlocks( IndexBlock, Scb->ScbType.Index.IndexBlockByteShift ), Scb->ScbType.Index.BytesPerIndexBuffer, &am…...
Vue3 + TypeSrcipt 防抖、防止重复点击实例
需要实现防抖应用场景: 点击【查询】按钮,发送网络请求,等待并接收响应数据 原来点击【查询】的代码: <script setup lang"ts" name"ReagentTransactionsDrawer"> ...... // 查询,没有防…...
SQL进阶之旅 Day 14:数据透视与行列转换技巧
【SQL进阶之旅 Day 14】数据透视与行列转换技巧 开篇 欢迎来到“SQL进阶之旅”系列的第14天!今天我们将探讨数据透视与行列转换技巧,这是数据分析和报表生成中的核心技能。无论你是数据库开发工程师、数据分析师还是后端开发人员,行转列或列…...

打通印染车间“神经末梢”:DeviceNet转Ethernet/IP连接机器人的高效方案
在印染行业自动化升级中,设备联网需求迫切。老旧印染设备多采用Devicenet协议,而新型工业机器人普遍支持Ethernet/IP协议,协议不兼容导致数据交互困难,设备协同效率低、生产监控滞后,成了行业数字化转型的阻碍。本文将…...
Ubuntu挂载本地镜像源(像CentOS 一样挂载本地镜像源)
1.挂载 ISO 镜像 sudo mount -o loop /ubuntu-22.04.5-desktop-amd64.iso /mnt/iso 2.备份现有的软件源配置文件: sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak 3.编辑软件源配置文件 编辑 /etc/apt/sources.list sudo nano /etc/apt/sources.l…...

2025-06-02-IP 地址规划及案例分析
IP 地址规划及案例分析 参考资料 Plan for IP addressing - Cloud Adoption Frameworkwww.cnblogs.comimage-hosting/articles at master jonsam-ng/image-hosting 概述 在网络通信中,MAC 地址与 IP 地址分别位于 OSI 模型的数据链路层和网络层,二者协…...

AUTOSAR实战教程--开放式通用DoIP刷写工具OpenOTA开发计划
目录 软件概述 安装与运行 界面说明 3.1 功能区划分 3.2 状态显示 基本操作流程 4.1 DoIP连接配置 4.2 服务配置(刷写流程) 4.3 执行操作 4.4 保存配置 4.5 加载配置 功能详解 5.1 核心功能模块 诊断服务配置 通信设置 文件下载 工具功…...
Vue 学习路线图(从零到实战)
🎯 学习目标:掌握 Vue 并能独立开发中大型项目 ✅ 适合人群:前端初学者、想快速上手做项目的开发者、中小型团队成员 🧭 Vue 学习路线图(从零到实战) 第一阶段:基础语法 核心功能(…...

AI赋能的浏览器自动化:Playwright MCP安装配置与实操案例
以下是对Playwright MCP的简单介绍: Playwright MCP 是一个基于 Playwright 的 MCP 工具,提供浏览器自动化功能不要求视觉模型支持,普通的文本大语言模型就可以通过结构化数据与网页交互支持多种浏览器操作,包括截图、点击、拖动…...
AI编程助手入门指南:GitHub Copilot、Cursor与Claude的安装与基础使用
🔥 AI编程助手入门指南:GitHub Copilot、Cursor与Claude的安装与基础使用 你是否曾幻想过拥有一个24小时在线的编程搭档?它能理解你的思路、自动补全代码、解释复杂逻辑,甚至帮你调试错误?如今,这个幻想已成…...
Android 线性布局中常见的冲突属性总结
1. gravity vs layout_gravity 冲突原因:两者作用对象不同,混用会导致行为异常。 区别: android:gravity:父容器的属性,控制子元素在容器内的对齐方式。android:layout_gravity:子元素的属性,控…...

【技术笔记】MSYS2 指定 Python 版本安装方案
#工作记录 MSYS2 指定 Python 版本安装 一、前置条件 安装指定版本需要在干净的 MSYS2 环境中执行,为保证工具链的兼容性,若已安装 Python,需先卸载 Python 及与该版本深度绑定的工具链。具体操作如下: 卸载 Python:…...

《校园生活平台从 0 到 1 的搭建》第一篇:创建项目与构建目录结构
在本系列第一篇中,我们将从项目初始化开始,搭建基本的目录结构,并完成四个主页面的创建与 TabBar 设置。 (tip:你可能会觉得有点 ai 化,因为这个文案是我自己写了一遍文案之后让 ai 去优化输出的࿰…...
Boost ASIO 库深入学习(3)
Boost ASIO 库深入学习(3) UDP简单通信导论 在继续深入前,我们不妨也来点碎碎念,因为UDP通信协议的模型与TCP是不同的,这种差异正是理解“无连接通信”的关键所在。我们下面要构建的,是一个经典的UDP通信…...