HTTP报文格式
HTTP请求报文格式
1. 结构:
[请求行]
[请求头]
[空行]
[请求体] (可选)
-
请求行:
方法 URI HTTP版本
常见方法:GET
(获取资源)、POST
(提交数据)、PUT
(替换资源)、DELETE
(删除资源)。
例如:GET /index.html HTTP/1.1
-
请求头:键值对形式,传递附加信息(如客户端信息、内容类型等)。
常见字段:Host: www.example.com
(目标域名,HTTP/1.1必需)User-Agent: Mozilla/5.0
(客户端信息)Accept: text/html
(客户端可接受的响应类型)Content-Type: application/json
(请求体类型,POST/PUT时使用)Content-Length: 27
(请求体的字节长度)
-
请求体:仅某些方法(如POST、PUT)携带,如提交表单或JSON数据。
2. 示例(GET请求):
http
GET /page.html HTTP/1.1
Host: www.example.com
User-Agent: Mozilla/5.0
Accept: text/html
3. 示例(POST请求):
POST /login HTTP/1.1
Host: www.example.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 29username=test&password=1234
4. 判断请求头结束的方式
1. 无消息体的请求(如GET、HEAD、DELETE等)
- 结束标志:请求头(Headers)之后紧跟两个连续的CRLF(即空行),此时请求结束。
- 示例:
GET /index.html HTTP/1.1\r\n Host: example.com\r\n \r\n
2. 有消息体的请求(如POST、PUT等)
对于包含消息体的请求,需通过以下方式确定结束:
a. 使用 Content-Length
头部
- 作用:明确指定消息体的字节长度。
- 判断方式:服务端读取完指定长度的字节后,视为请求结束。
- 示例:
POST /upload HTTP/1.1\r\n Content-Length: 1234\r\n \r\n <1234字节的数据>
b. 使用分块传输编码(Transfer-Encoding: chunked
)
- 作用:将消息体分块传输,适用于动态生成内容或无法预知内容大小的情况。
- 判断方式:
- 每个分块以十六进制长度开头,后跟CRLF和数据块。
- 以长度标识为
0
的块表示结束,后跟最终的CRLF。
- 示例:
POST /data HTTP/1.1\r\n Transfer-Encoding: chunked\r\n \r\n 5\r\n Hello\r\n 0\r\n \r\n
c. 无Content-Length
与Transfer-Encoding
的情况
- HTTP/1.0:无持久连接时,可能依赖客户端关闭连接判断结束(不推荐用于HTTP/1.1)。
- HTTP/1.1:规范要求必须明确指定长度或使用分块编码,否则服务器会返回
400 Bad Request
错误。
3. 其他注意事项
- Expect头处理:若请求包含
Expect: 100-continue
,服务端需先响应100 Continue
状态码,再按规则处理消息体。 - 协议版本差异:HTTP/1.1严格要求使用
Content-Length
或分块编码处理持久连接中的请求,而HTTP/1.0可能允许通过关闭连接判断结束。
总结流程图
开始接收请求
├─ 读取请求头直至空行(\r\n\r\n)
├─ 判断是否存在消息体?
│ ├─ 否 → 请求结束
│ └─ 是 → 检查头部:
│ ├─ 若有Content-Length → 读取指定字节数后结束
│ ├─ 若Transfer-Encoding: chunked → 解析分块直至遇到长度0块
│ └─ 无明确标识 → 按协议版本处理(HTTP/1.1返回错误,HTTP/1.0可能读取到连接关闭)
结束
HTTP响应报文格式
1. 结构:
[状态行]
[响应头]
[空行]
[响应体] (可选)
-
状态行:
HTTP版本 状态码 状态消息
常见状态码:200 OK
:成功404 Not Found
:资源未找到500 Internal Server Error
:服务器错误301 Moved Permanently
:永久重定向
-
响应头:提供服务器信息或资源元数据。
常见字段:Server: Apache/2.4
(服务器信息)Content-Type: text/html
(响应体类型)Content-Length: 1024
(响应体的字节长度)Set-Cookie: session=abc123
(设置Cookie)
-
响应体:请求资源的内容(如HTML、JSON、图片等)。
-
判断HTTP响应结束的方式:
-
Content-Length准则
- 当响应头包含
Content-Length
时,消息体需精确读取指定字节数 - 示例行为:
inputStream.read(body)
严格读取给定长度
- 当响应头包含
-
Chunked分块准则
- 当
Transfer-Encoding: chunked
时,循环读取格式为:[块大小]\r\n[块数据]\r\n
- 终止条件:读取到
0\r\n
表示所有分块传输完成
- 当
-
连接关闭准则
- 无上述头部且非持久连接时,持续读取直到
inputStream.read()
返回-1
- 无上述头部且非持久连接时,持续读取直到
// 伪代码演示HTTP响应结束判断
class HttpResponseParser {void parseResponse(InputStream inputStream) throws IOException {BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));Map<String, String> headers = new HashMap<>();String line;// 1. 解析响应头while ((line = reader.readLine()) != null) {if (line.isEmpty()) break; // 头部结束标记(空行)if (line.contains(":")) {String[] parts = line.split(":", 2);headers.put(parts[0].trim().toLowerCase(), parts[1].trim());}}// 2. 判断消息体结束规则if (headers.containsKey("content-length")) {// 情况1:通过Content-Length确定结束位置int length = Integer.parseInt(headers.get("content-length"));byte[] body = new byte[length];inputStream.read(body); // 严格读取指定长度processBody(body);} else if ("chunked".equals(headers.get("transfer-encoding"))) {// 情况2:通过分块编码判断结束while (true) {String chunkSizeLine = reader.readLine();int chunkSize = Integer.parseInt(chunkSizeLine.split(";")[0], 16); // 解析16进制长度if (chunkSize == 0) break; // 结束标记byte[] chunk = new byte[chunkSize];inputStream.read(chunk);reader.readLine(); // 丢弃块结束的CRLFprocessChunk(chunk);}} else {// 情况3:持续读取直到流关闭(HTTP/1.0旧模式)ByteArrayOutputStream buffer = new ByteArrayOutputStream();int b;while ((b = inputStream.read()) != -1) { // -1表示流结束buffer.write(b);}processBody(buffer.toByteArray());}}// 示例方法:处理完整消息体void processBody(byte[] data) { /* ... */ }// 示例方法:处理分块数据void processChunk(byte[] chunk) { /* ... */ }
}
2. 示例(成功响应HTML):
http
HTTP/1.1 200 OK
Server: Nginx
Content-Type: text/html
Content-Length: 158<html><head><title>示例页面</title></head><body>Welcome!</body>
</html>
3. 示例(错误响应):
http
HTTP/1.1 404 Not Found
Content-Type: text/plain
Content-Length: 15Page not found.
4. 示例(JSON响应):
http
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 28{"status": "success", "data": {}}
完整交互示例
客户端访问 https://www.example.com/index.html
:
- 请求:
http
GET /index.html HTTP/1.1
Host: www.example.com
User-Agent: Mozilla/5.0
Accept: text/html
- 响应:
http
HTTP/1.1 200 OK
Server: Apache/2.4
Content-Type: text/html
Content-Length: 1234<!DOCTYPE html>
<html>...</html>
关键注意事项
- 空行分隔:头部和主体间必须有一个仅包含CRLF的空行。
- 方法区分:GET一般无请求体,POST/PUT通过
Content-Type
和Content-Length
指定请求体格式。 - 无状态协议:HTTP协议本身不保存状态,依赖Cookie/Session等机制。
- 扩展性:可通过自定义头部字段(如
Authorization: Bearer token
)实现扩展功能。
掌握HTTP报文格式能帮助理解Web开发、API设计和网络调试(如使用浏览器开发者工具或Fiddler抓包)。
相关文章:
HTTP报文格式
HTTP请求报文格式 1. 结构: [请求行] [请求头] [空行] [请求体] (可选)请求行:方法 URI HTTP版本 常见方法:GET(获取资源)、POST(提交数据)、PUT(替…...
pytest.fixture
pytest.fixture 是 pytest 测试框架中的一个非常强大的功能,它允许你在测试函数运行前后执行一些设置或清理代码。以下是关于 pytest.fixture 的详细介绍: 一、定义与用途 pytest.fixture 是一个装饰器,用于标记一个函数为 fixture。Fixture 函数中的代码可以在测试函数运…...
位运算算法篇:进入位运算的世界
位运算算法篇:进入位运算的世界 本篇文章是我们位运算算法篇的第一章,那么在我们是算法世界中,有那么多重要以及有趣的算法,比如深度优先搜索算法以及BFS以及动态规划算法等等,那么我们位运算在这些算法面前相比&#…...
Heterogeneous Graph Attention Network(HAN)
HAN WWW19 分类:异构图神经网络 元路径 (图片地址:异构图注意力网络(3) HAN_哔哩哔哩_bilibili) 如图所示,假如异构图如上所示。那么,按照MAM和MDM就可以生成不同的子图。这样,就可以生成MAM与MDM的一阶邻居…...
重学SpringBoot3-Spring WebFlux之SSE服务器发送事件
更多SpringBoot3内容请关注我的专栏:《SpringBoot3》 期待您的点赞??收藏评论 Spring WebFlux之SSE服务器发送事件 1. 什么是 SSE?2. Spring Boot 3 响应式编程与 SSE 为什么选择响应式编程实现 SSE? 3. 实现 SSE 的基本步骤 3.1 创建 Spr…...
Java中实现定时锁屏的功能(可以指定时间执行)
Java中实现定时锁屏的功能(可以指定时间执行) 要在Java中实现定时锁屏的功能,可以使用java.util.Timer或java.util.concurrent.ScheduledExecutorService来调度任务,并通过调用操作系统的命令来执行锁屏。下面我将给出一个基本的…...
工作案例 - python绘制excell表中RSRP列的CDF图
什么是CDF图 CDF(Cumulative Distribution Function)就是累积分布函数,是概率密度函数的积分。CDF函数是一个在0到1之间的函数,描述了随机变量小于或等于一个特定值的概率。在可视化方面,CDF图表明了一个随机变量X小于…...
推理大模型DeepSeek迅速觉醒
随着人工智能技术的快速发展,DeepSeek作为一种创新的技术工具,正在重塑行业格局。本文将深入分析如何把握这一波由DeepSeek带来的流量红利,揭示其在市场洞察、技术创新和用户需求中的潜在机会,并提供实用策略帮助个人或企业快速融…...
Ubuntu22.04部署deepseek大模型
Ollama 官方版 Ollama 官方版: https://ollama.com/ 若你的显卡是在Linux上面 可以使用如下命令安装 curl -fsSL https://ollama.com/install.sh | shollama命令查看 rootheyu-virtual-machine:~# ollama -h Large language model runnerUsage:ollama [flags]ollama [comman…...
redis的数据结构介绍(string
redis是键值数据库,key一般是string类型,value的类型很多 string,hash,list,set,sortedset,geo,bitmap,hyperlog redis常用通用命令: keys: …...
QUIC 与 UDP 关系
QUIC协议是建立在UDP之上的,这意味着QUIC的数据包实际上是通过UDP传输的。QUIC的设计使其能够利用UDP的特性,同时在其上实现更复杂的功能。以下是QUIC如何体现出其基于UDP的特性,以及QUIC头部字段的详细介绍。 QUIC与UDP的关系 UDP封装:QUIC数据包被封装在UDP数据包中进行…...
webview_flutter的使用
目录 步骤示例代码 步骤 1.配置依赖。根目录下运行如下命令: flutter pub add webview_flutter 2.所需页面导入: import ‘package:webview_flutter/webview_flutter.dart’; 3.初始化WebViewController overridevoid initState() {super.initState();…...
Centos执行yum命令报错
错误描述 错误:为仓库 ‘appstream’ 下载元数据失败 : Cannot prepare internal mirrorlist: Curl error (6): Couldn’t resolve host name for http://mirrorlist.centos.org/?release8&archx86_64&repoAppStream&infrastock [Could not resolve h…...
aio-pika 快速上手(Python 异步 RabbitMQ 客户端)
目录 简介官方文档如何使用 简介 aio-pika 是一个 Python 异步 RabbitMQ 客户端。5.0.0 以前 aio-pika 基于 pika 进行封装,5.0.0 及以后使用 aiormq 进行封装。 https://github.com/mosquito/aio-pikahttps://pypi.org/project/aio-pika/ pip install aio-pika官…...
AI安全最佳实践:AI应用开发安全评估矩阵(上)
生成式AI开发安全范围矩阵简介 生成式AI目前可以说是当下最热门的技术,吸引各大全球企业的关注,并在全球各行各业中带来浪潮般的编个。随时AI能力的飞跃,大语言模型LLM参数达到千亿级别,它和Transformer神经网络共同驱动了我们工…...
疯狂前端面试题(二)
一、Webpack的理解 Webpack 是一个现代 JavaScript 应用程序的静态模块打包工具。Webpack 能够将各种资源(JavaScript、CSS、图片、字体等)视为模块,并通过依赖关系图将这些模块打包成一个或多个最终的输出文件(通常是一个或几个…...
深入探究 C++17 std::is_invocable
文章目录 一、引言二、std::is_invocable 概述代码示例输出结果 三、std::is_invocable 的工作原理简化实现示例 四、std::is_invocable 的相关变体1. std::is_invocable_r2. std::is_nothrow_invocable 和 std::is_nothrow_invocable_r 五、使用场景1. 模板元编程2. 泛型算法 …...
【R语言】卡方检验
一、定义 卡方检验是用来检验样本观测次数与理论或总体次数之间差异性的推断性统计方法,其原理是比较观测值与理论值之间的差异。两者之间的差异越小,检验的结果越不容易达到显著水平;反之,检验结果越可能达到显著水平。 二、用…...
DeepSeek LLM 论文解读:相信长期主义开源理念可扩展大语言模型(DeepSeek 吹响通用人工智能的号角)
论文链接:DeepSeek LLM: Scaling Open-Source Language Models with Longtermism(相信长期主义开源理念可扩展大语言模型) 目录 摘要一、数据处理(一)数据清洗与丰富(二)分词器与词汇设置 二、模…...
指针基础知识2
1. 指针运算 1.1 指针 - 整数 以数组举例:因为数组在内存中是连续存放的,只要知道第⼀个元素的地址,顺藤摸瓜就能找到后面的所有元素。这时就会用到指针加减整数。 1.2指针-指针 指针 - 指针可以得到两个指针之间的数据个数。但是…...
nginx的4层和7层配置证书
4层证书代理 # 定义上游服务器组 stream {upstream tcp-25510 {hash $remote_addr consistent;server ip:5510;}# 配置监听 25510 端口的服务器块server {listen 25510 ssl; # 监听 25510 端口并启用 SSL# 指定 SSL 证书和私钥ssl_certificate /etc/nginx/key/bundle.crt;ssl…...
【大数据技术】搭建完全分布式高可用大数据集群(Flume)
搭建完全分布式高可用大数据集群(Flume) apache-flume-1.11.0-bin.tar.gz注:请在阅读本篇文章前,将以上资源下载下来。 写在前面 本文主要介绍搭建完全分布式高可用集群 Flume 的详细步骤。 注意: 统一约定将软件安装包存放于虚拟机的/software目录下,软件安装至/opt目…...
C++ 顺序表
顺序表的操作有以下: 1 顺序表的元素插入 给定一个索引和元素,这个位置往后的元素位置都要往后移动一次,元素插入的步骤有以下几步 (1)判断插入的位置是否合法,如果不合法则抛出异常 (2&…...
Python----Python高级(网络编程:网络基础:发展历程,IP地址,MAC地址,域名,端口,子网掩码,网关,URL,DHCP,交换机)
一、网络 早期的计算机程序都是在本机上运行的,数据存储和处理都在同一台机器上完成。随着技术的发展,人 们开始有了让计算机之间相互通信的需求。例如安装在个人计算机上的计算器或记事本应用,其运行环 境仅限于个人计算机内部。这种设置虽然…...
Spring Boot 的问题:“由于无须配置,报错时很难定位”,该怎么解决?
Spring Boot 的 "由于无须配置,报错时很难定位" 主要指的是: 传统 Spring 框架 需要大量 XML 或 Java 配置,开发者对应用的组件、Bean 加载情况有清晰的控制,出错时可以从配置入手排查。Spring Boot 采用自动配置&…...
基于javaweb的SpringBoot小区智慧园区管理系统(源码+文档+部署讲解)
🎬 秋野酱:《个人主页》 🔥 个人专栏:《Java专栏》《Python专栏》 ⛺️心若有所向往,何惧道阻且长 文章目录 运行环境开发工具适用功能说明 运行环境 Java≥8、MySQL≥5.7、Node.js≥14 开发工具 后端:eclipse/idea/myeclipse…...
一文解释nn、nn.Module与nn.functional的用法与区别
🌈 个人主页:十二月的猫-CSDN博客 🔥 系列专栏: 🏀零基础入门PyTorch框架_十二月的猫的博客-CSDN博客 💪🏻 十二月的寒冬阻挡不了春天的脚步,十二点的黑夜遮蔽不住黎明的曙光 目录 …...
vscode安装ESP-IDF
引言 ESP-IDF(Espressif IoT Development Framework)是乐鑫官方为其 ESP32、ESP32-S 系列等芯片提供的物联网开发框架。结合 Visual Studio Code(VSCode)这一强大的开源代码编辑器,能极大提升开发效率。本教程将详细介…...
springboot配置https
注意: 此配置只能本地环境或测试环境使用,生产环境使用https,应该配置nginx!请参考:使用certbot给nginx配置https-CSDN博客 1. 生成证书 使用JDK的keytool命令生成证书 注意:JDK版本需要和项目的JDK版本一…...
数据库的关系代数
关系就是表 属性(Attribute)是关系中的列.例如,关系 “学生” 中可能有属性 “学号”、“姓名”、“班级”。 元组(Tuple)是关系中的一行数据 1. 基本运算符 选择(Selection) 符号:σ 作用:从关…...
【服务器知识】如何在linux系统上搭建一个nfs
文章目录 NFS网络系统搭建**1. 准备工作****2. 服务器端配置****(1) 安装 NFS 服务****(2) 创建共享目录****(3) 配置共享规则****(4) 生效配置并启动服务****(5) 防火墙配置** **3. 客户端配置****(1) 安装 NFS 客户端工具****(2) 创建本地挂载点****(3) 挂载 NFS 共享目录***…...
【学习总结|DAY037】Linux 项目部署
引言 在当今的软件开发领域,Linux 以其安全、稳定、免费且开源的特性,成为项目部署的首选操作系统。无论是 Java 项目,还是各类开发、测试、生产环境中的软件安装,Linux 都占据着重要地位。本文将结合我今天所学内容,…...
【算法】动态规划专题⑧ —— 分组背包问题 python
目录 前置知识进入正题实战演练总结 前置知识 【算法】动态规划专题⑤ —— 0-1背包问题 滚动数组优化 python 进入正题 分组背包问题的详细解析 1. 问题定义 在 分组背包问题 中,物品被划分为若干组,每组内的物品 互斥(只能选择其中一个或…...
数据结构:算法复杂度
前言 数据结构(Data Structure)是计算机存储、组织数据的方式,指相互之间存在一种或多种特定关系的数据元素的集合。没有一种单一的数据结构对所有用途都有用,所以我们要学各式各样的数据结构,如:线性表、树…...
Mac本地体验LM studio
博主很懒,不爱打字! 1、LM studio官网:LM Studio - Discover, download, and run local LLMs 2、下载DMG文件,安装 3、使用vscode工具,commandshiftH【全局替换功能】,选择目录/Applications/LM\ Studio…...
【EPSG 坐标系系统完全解析(一)(8000 字终极指南)】
EPSG 坐标系系统完全解析(8000 字终极指南) 一、EPSG 的起源与定义(1200 字) 1.1 石油工业催生的标准 行业需求:20 世纪 80 年代石油勘探需要统一坐标参考成立过程: 1985 年欧洲石油公司成立 EPSG 工作组…...
【C++高并发服务器WebServer】-13:多线程服务器开发
本文目录 一、多线程服务器开发二、TCP状态转换三、端口复用 一、多线程服务器开发 服务端代码如下。 #include <stdio.h> #include <arpa/inet.h> #include <unistd.h> #include <stdlib.h> #include <string.h> #include <pthread.h>s…...
【CubeMX-HAL库】STM32F407—无刷电机学习笔记
目录 简介: 学习资料: 跳转目录: 一、工程创建 二、板载LED 三、用户按键 四、蜂鸣器 1.完整IO控制代码 五、TFT彩屏驱动 六、ADC多通道 1.通道确认 2.CubeMX配置 ①开启对应的ADC通道 ②选择规则组通道 ③开启DMA ④开启ADC…...
mysql8 sql语法错误,错误信息是怎么通过网络发送给客户端的,C++源码展示
在 MySQL 8 中,错误信息通过网络发送给客户端的过程涉及多个步骤,主要包括错误信息的生成、格式化、以及通过网络协议(如 TCP/IP)将错误信息发送给客户端。以下是详细的流程和相关代码分析: 1. 错误信息的生成 当 My…...
人工智能D* Lite 算法-动态障碍物处理、多步预测和启发式函数优化
在智能驾驶领域,D* Lite 算法是一种高效的动态路径规划算法,适用于处理环境变化时的路径重规划问题。以下将为你展示 D* Lite 算法的高级用法,包含动态障碍物处理、多步预测和启发式函数优化等方面的代码实现。 代码实现 import heapq impo…...
【学术投稿】第五届计算机网络安全与软件工程(CNSSE 2025)
重要信息 官网:www.cnsse.org 时间:2025年2月21-23日 地点:中国-青岛 简介 第五届计算机网络安全与软件工程(CNSSE 2025)将于2025年2月21-23日在中国-青岛举行。CNSSE 2025专注于计算机网络安全、软件工程、信号处…...
spring学习(spring 配置文件详解)
一 了解如何创建基本的spring 配置文件 步骤 1 导入 spring-context 依赖 <!-- https://mvnrepository.com/artifact/org.springframework/spring-context --><dependency><groupId>org.springframework</groupId><artifactId>spring-context&l…...
创建一个javaWeb Project
文章目录 前言一、eclipse创建web工程二、web.xmlservlet.xml< mvc:annotation-driven/ > Spring MVC 驱动< context:component - scan >:扫描< bean > ... < /bean >< import > config/beans.xml beans.xmlmybatis.xml 前言 javaWe…...
大模型推理——MLA实现方案
1.整体流程 先上一张图来整体理解下MLA的计算过程 2.实现代码 import math import torch import torch.nn as nn# rms归一化 class RMSNorm(nn.Module):""""""def __init__(self, hidden_size, eps1e-6):super().__init__()self.weight nn.Pa…...
洛谷网站: P3029 [USACO11NOV] Cow Lineup S 题解
题目传送门: P3029 [USACO11NOV] Cow Lineup S - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 前言: 这道题的核心问题是在一条直线上分布着不同品种的牛,要找出一个连续区间,使得这个区间内包含所有不同品种的牛,…...
DeepSeek-R1 云环境搭建部署流程
DeepSeek横空出世,在国际AI圈备受关注,作为个人开发者,AI的应用可以有效地提高个人开发效率。除此之外,DeepSeek的思考过程、思考能力是开放的,这对我们对结果调优有很好的帮助效果。 DeepSeek是一个基于人工智能技术…...
【Go语言快速上手】第二部分:Go语言进阶
文章目录 并发编程goroutine:创建和调度 goroutinechannel:无缓冲 channel、有缓冲 channel、select 语句无缓冲 channel有缓冲 channelselect 语句 sync 包:Mutex、RWMutex、WaitGroup 等同步原语Mutex:互斥锁RWMutex:…...
自定义多功能输入对话框:基于 Qt 打造灵活交互界面
一、引言 在使用 Qt 进行应用程序开发时,我们经常需要与用户进行交互,获取他们输入的各种信息。QInputDialog 是 Qt 提供的一个便捷工具,可用于简单的输入场景,但当需求变得复杂,需要支持更多类型的输入控件࿰…...
计算机毕业设计SparkStreaming+Kafka广告推荐系统 广告预测 广告数据分析可视化 广告爬虫 大数据毕业设计 深度学习 机器学习
温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 作者简介:Java领…...
企业FTP替代升级,实现传输大文件提升100倍!
随着信息技术的飞速发展,网络安全环境也变得越来越复杂。在这种背景下,传统的FTP(文件传输协议)已经很难满足现代企业对文件传输的需求了。FTP虽然用起来简单,但它的局限性和安全漏洞让它在面对高效、安全的数据交换时…...