应用层自定义协议
自定义协议是指根据特定需求设计的通信规则,用于设备或系统间的数据交换。其核心在于定义数据结构、传输方式及处理逻辑。
协议结构示例
典型的自定义协议包含以下部分:
- 头部(Header):标识协议版本、数据长度、校验码等元信息。
- 载荷(Payload):实际传输的数据内容,格式可自定义(如键值对、二进制流)。
- 尾部(Footer):可选部分,用于标记数据包结束或附加校验。
自定义协议的流程
根据需要明确信息
根据需求,明确要传输什么信息。也就是明确客户端和用户端之间要请求和响应的具体信息是什么。
约定好信息组织的格式
行文本的方式:
//一个响应用多行组成,每一行是一个商家
商家id,商家名称,商家地址\n
通过xml格式来约定:
xml是成对的标签构成的键对值结构,是一种用于存储和传输数据的标记语言。可读性好但数据冗余信息太多了,会消耗太多的带宽。
<request><userId>1000</userId><position>75E75N</position>
</request>
<response><shop><id>1</id><name>杨国福</name><image>1.jpg</image><rank>5.0</rank><sendprice>5</sendprice></shop>
</response>
通过json网络数据格式(主流方式)
是一种轻量级的数据交换格式,采用文本格式存储和传输数据。其结构基于键值对和有序列表,易于人阅读和编写,也便于机器解析和生成。可读性好,但相比xml来说依然还有冗余。
{"request": {"userId": 1000,"position": "75E75N"},"response": {"shop": {"id": 1,"name": "杨国福","image": "1.jpg","rank": 5.0,"sendprice": 5}}
}
protobuf
基于二进制编码,体积小,速度快,支持数据的高效序列化和反序列化。但可读性差,冗余最小。
syntax = "proto3";message Person {string name = 1;int32 id = 2;repeated string emails = 3; // 重复字段(类似数组)
}
其他
在应用层协议中除了自定义协议的情况下,还有一些大佬已经现成搞好的协议,如:FTP文件传输,SSH远程操作主机,HTTP协议等,还接下里我们将重点取讲解HTTP协议,
HTTP(超文本传输协议)
HTTP是一种用于传输超文本(如HTML)的应用层协议,是万维网(WWW)数据通信的基础。它基于客户端-服务器模型,通过请求-响应机制(一对一)实现资源交换。是当下主流使用的一种应用层协议,像我们平常打开一个网站就是通过HTTP协议来传输数据的。
"超⽂本"的含义,就是传输的内容不仅仅是⽂本(⽐如html,css这个就是⽂本),还可以是⼀些其 他的资源,⽐如图⽚,视频,⾳频等⼆进制的数据。
工作过程
当我们在浏览器中输⼊⼀个"⽹址",此时浏览器就会给对应的服务器发送⼀个HTTP请求.对⽅服务器 收到这个请求之后,经过计算处理,就会返回⼀个HTTP响应。
在实际过程中可能不止一个HTTP请求。响应的交互过程。
HTTP协议格式
需要搭配Fiddler工具(抓包工具)主要用于捕获、分析和修改HTTP/HTTPS流量,适用于Web开发、测试及网络安全分析。(这里就不介绍Fiddler工具的使用)。
1. HTTP 请求格式
- 请求行(Request Line)[⽅法]+[url]+[版本]
- 请求头(Header)请求的属性,冒号分割的键值对;每组属性之间使⽤\n分隔;遇到空⾏表⽰Header部分结束
- 空行(CRLF)
- 请求体(Body,可选)Body允许为空字符串.如果Body存在,则在Header中会有⼀个 Content-Length属性来标识Body的⻓度
2. HTTP 响应格式
- 状态行(Status Line)[版本号]+[状态码]+[状态码解释]
- 响应头(Header)请求的属性,冒号分割的键值对;每组属性之间使⽤\n分隔;遇到空⾏表⽰Header部分结束
- 空行(CRLF)
- 响应体(Body,可选)Body允许为空字符串.如果Body存在,则在Header中会有⼀个 Content-Length属性来标识Body的⻓度;如果服务器返回了⼀个html⻚⾯,那么html⻚⾯内容就是 在body中
总结
HTTP请求(Request)
认识URL
URL(Uniform Resource Locator,统一资源定位符)是互联网上用于定位资源(如网页、图片、文件等)的地址,就像资源的 “唯一坐标”,能让浏览器或其他工具准确找到并获取它。
URL的基本格式
协议类型:[//服务器地址[:端口号]][/资源层级 UNIX 文件路径]文件名[?查询字符串][#片段标识符]
URL的完整格式
协议类型:[//[访问资源需要的凭证信息@]服务器地址[:端口号]][/资源层级 UNIX 文件路径]文件名[?查询字符串][#片段标识符]
URL参数介绍
URL组成参数详解
以下是基于您提供的内容,以表格形式呈现的URL参数部分详解。表格严格遵循您的原始内容,未做任何修改,仅进行格式化处理。
参数部分 | 格式示例 | 含义与作用 | 常见形式 / 说明 |
---|---|---|---|
协议类型(Scheme) | http://、https:// | 指定客户端与服务器通信的协议规则,决定资源传输方式和安全机制 | - 常见协议:http(非加密网页传输)、https(加密传输,用于隐私场景),可以省略,省略后默认为 http://。 |
[访问资源需要的凭证信息 @] | user:password@ | 可选,用于向服务器提供身份验证的用户名和密码 | 现在的⽹站进⾏⾝份认证⼀般不再通过URL进⾏了.⼀般都会省略 |
服务器地址(Host) | www.example.com、192.168.1.1 | 标识资源所在的服务器,用于定位目标服务器 | - 形式:域名(需 DNS 解析为 IP)或直接 IP 地址(如114.114.114.114 是 URL 中定位服务器的核心标识 |
[: 端口号] | :8080、:443 | 服务器上区分不同服务的数字标识(0-65535) | - 默认端口可省略:http默认 80、https默认 443、ftp默认 21 示例:https://example.com:8080表示通过 8080 端口访问 HTTPS 服务 |
[/ 资源层级 UNIX 文件路径] | /blog/2023/articles/ | 资源在服务器上的存储路径,类似本地文件系统的层级结构 | - 以 “/” 分隔目录层级,对应服务器上的文件夹结构<br>- 用于定位资源所在的具体目录(如子文件夹) |
文件名 | index.html、photo.jpg | 具体资源的名称,通常包含文件扩展名 | - 常见类型:网页文件(.html)、图片(.jpg/.png)、文档(.pdf)等-省略时,服务器可能默认返回index.html等首页文件(由服务器配置决定) |
[? 查询字符串] | ?keyword=url&page=1 | 客户端向服务器传递的额外参数,用于动态筛选或查询资源 | 本质是⼀个键值对结构.键值对之 间使⽤&分隔.键和值之间使⽤=分隔. |
[# 片段标识符] | #section3 | 用于定位资源内部的具体位置 | - 以 “#” 开头,对应网页中的锚点(如<a id="section3">)<br>- 浏览器会直接跳转到该位置,不会将此部分发送给服务器 |
典型URL示例解析
https://admin:pass123@api.example.com:8443/v1/data?type=user#permissions
- 协议类型:
https://
表示加密传输 - 凭证信息:
admin:pass123@
提供基础认证凭据(高风险,仅演示) - 服务器地址:
api.example.com
指向API服务域名 - 端口号:
:8443
使用非标准HTTPS端口 - 资源路径:
/v1/data
表示API版本及数据端点 - 查询参数:
?type=user
筛选用户类型数据 - 片段标识:
#permissions
跳转到权限相关章节
URLencode
是一种将 URL 中不符合规范的字符转换为特定格式的编码方式,目的是确保 URL 能被正确传输和解析。因为 URL 的某些字符(如空格、特殊符号等)可能被浏览器或服务器误解,或在传输中出现歧义,所以需要通过编码统一格式。
保留字符不编码
URL 中有一部分字符是 “保留字符”,具有特殊含义(如 : / ? # [ ] @ ! $ & ' ( ) * + , ; =
等),若需作为普通字符使用则需编码,否则不编码。
非保留字符不编码
字母(a-z
、A-Z
)、数字(0-9
)以及部分符号(- _ . ~
)属于 “非保留字符”,无需编码,直接保留原样。
其他字符需编码
除上述两类外的字符(如空格、中文、特殊符号等),需转换为 %XX
格式(XX
为该字符的 ASCII 码十六进制表示)。
示例
在浏览器中搜索小黑++
https://www.sogou.com/web?query=%E5%B0%8F%E9%BB%91%2B%2B&_asf=www.sogou.com&_ast=&w=01019900&p=40040100&ie=utf8&from=index-nologin&s_from=index&sourceid=9_01_03&sessiontime=1755002253615 HTTP/1.1
我们会发现这个值%E5%B0%8F%E9%BB%91%2B%2B&通过 urldecode我们会发先这是小黑++的意思。
认识"⽅法"(method)
HTTP 协议定义了多种请求方法,每种方法对应不同的操作类型,用于客户端向服务器请求资源或对资源进行操作。
常用的方法:GET,POT,PUT,DELETE
GET 方法
用于从服务器获取资源。这是最常用的方法,当在浏览器中输入网址访问网页,或通过链接跳转页面时,浏览器通常使用 GET 方法向服务器请求资源。
GET 请求的特点:
- 首行里面的第一个部分就是 GET
- URL 里面的 query string 可以为空,也可以不为空
- header 有若干个键值对结构
- body 一般是空的
GET 请求示例: 搜狗首页请求
POST 方法
用于向服务器提交数据,通常用于创建新资源。比如用户注册、登录时提交表单数据,或者上传文件等操作,常使用 POST 方法。
POST 请求的特点:
- 首行第一个部分就是 POST
- URL 里面的 query string 一般是空的
- header 里面有若干个键值对
- body 一般不为空(body 的具体数据格式,由 header 中的 Content-Type 来描述;body 的具体数据长度,由 header 中的 Content-Length 来描述
这里的POST请求就不示例了可以自己在可以登录得网站上自己操作。
GET 和 POST 的区别
- 语义不同:GET⼀般⽤于获取数据,POST⼀般⽤于提交数据.
- GET的body⼀般为空,需要传递的数据通过querystring传递,POST的querystring⼀般为空,需 要传递的数据通过body传递
- GET请求⼀般是幂等的,POST请求⼀般是不幂等的.(如果多次请求得到的结果和一次请求得到的结果⼀样,就视为请求是 幂等的).
- GET可以被缓存,POST不能被缓存.(这⼀点也是承接幂等性)
认识请求"报头"(header)
header 的整体的格式也是"键值对"结构. 每个键值对占⼀⾏.键和值之间使⽤分号分割
Host
必不可少的报头,指定请求的目标服务器的域名和端口号(若端口号为默认值 80 或 443,端口号可省略)。例如,Host: www.sogou,com
,服务器根据这个报头确定客户端请求的具体网站,因为一台服务器可能托管多个网站。
Content-Length
指明请求体的长度(字节数),服务器根据此长度来准确读取请求体中的数据。例如,Content - Length: 100
表示请求体的大小为 100 字节。
Content-Type
当请求包含数据(如 POST 请求提交表单数据)时,此报头指定请求体中数据的类型。
常⻅选项:
application/x-www-form-urlencoded: form 表单提交的数据格式.此时body的格式形如:
title=test&content=hello
multipart/form-data: form 表单提交的数据格式(在form标签中加上 enctyped="multipart/form-data" .通常⽤于提交图⽚/⽂件.body格式形如:
Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryrGKCBY7qhFd3Trw------WebKitFormBoundaryrGKCBY7qhFd3TrwA
Content-Disposition: form-data; name="text"
title ------WebKitFormBoundaryrGKCBY7qhFd3TrwA
Content-Disposition: form-data; name="file"; filename="chrome.png"
Content-Type: image/png
PNG ... content of chrome.png ... ------WebKitFormBoundaryrGKCBY7qhFd3TrwA--
application/json: 数据为json格式.body格式形如:
{"username":"123456789","password":"xxxx","code":"jw7l","uuid":"d110a05ccde64b16
正⽂中的内容格式和header中的Content-Type密切相关
User-Agent(简称 UA)
包含发出请求的客户端应用程序的相关信息,如浏览器类型、版本、操作系统等。
Referer
表⽰这个⻚⾯是从哪个⻚⾯跳转过来的。
注意: 如果直接在浏览器中输入 URL 或直接通过收藏夹访问页面时,是没有 Referer 的
Cookie
Cookie 中存储了⼀个字符串,这个数据可能是客⼾端(⽹⻚)⾃⾏通过JS写⼊的,也可能来⾃于服务器 (服务器在HTTP响应的header中通过Set-Cookie字段给浏览器返回数据)
以登录为例
登录成功后Cookie会保存一个set-Cookie数据在本地,给用户一个令牌,再接下来访问页面的或下次访问页面过程中都会带上这个令牌,浏览器会在 HTTP 请求头中自动包含这个 Cookie,发送给服务器,表示此时是一个登录的状态,最终再返回服务器,同时Cookie令牌也会过期,比如说长时间不操作一个网站,此时令牌过期就会回到登录状态,提高安全性。而Cookie中的这些相关数据都是由程序员决定的。
HTTP响应详解
认识"状态码"(statuscode)
状态码表⽰访问⼀个⻚⾯的结果.(是访问成功,还是失败,还是其他的⼀些情况...),以下将介绍常用的状态码。
200OK
这是⼀个最常⻅的状态码,表⽰访问成功
404NotFound
没有找到资源,列入在浏览器中输⼊www.sogou.com/index2.html就会看到这样的响应
403Forbidden
表⽰访问被拒绝.有的⻚⾯通常需要⽤⼾具有⼀定的权限才能访问(登陆后才能访问).如果⽤⼾没有登陆 直接访问,就容易⻅到403
405 Method Not Allowed
表示访问的服务器不能支持请求中的方法或者不能使用该请求中的方法
500Internal Server Error
服务器出现内部错误.⼀般是服务器的代码执⾏过程中遇到了⼀些特殊情况(服务器异常崩溃)会产⽣这 个状态码
504GatewayTimeout
当服务器负载⽐较⼤的时候,服务器处理单条请求的时候消耗的时间就会很⻓,就可能会导致出现超时 的情况
302Movetemporarily
表示临时重定向
在登陆⻚⾯中经常会⻅到302.⽤于实现登陆成功后⾃动跳转到主⻚.
301 Moved Permanently
表示永久重定向,当浏览器收到这种响应时,后续的请求都会被自动改成新的地址
认识响应"报头"(header)
响应报头的基本格式和请求报头的格式基本⼀致
响应中的Content-Type常⻅取值有以下⼏种:
- t ext/html :body数据格式是HTML
- te xt/css :body数据格式是CSS
- a pplication/javascript :body数据格式是JavaScript
- a pplication/json :body数据格式是JSON
正⽂中的内容格式和header中的Content-Type密切相关就不详情介绍了可自己使用Fiddler工具去观察。
通过 form 表单构造 HTTP 请求
form 是 HTML 中的一个表单标签,可以用于给服务器发送 GET 或者 POST 请求。
form 的重要参数:
- action:用来构造 HTTP 请求的 URL 是什么
- method:用来构造 HTTP 请求的方法(form 只支持 GET 或 POST 方法)
input 的重要参数在 form 标签中的含义:
- type:表示输入框的类型(text 表示文本、password 表示密码、submit 表示提交按钮)
- name:表示构造出的 HTTP 请求的 query string 的 key
- value:表示 input 标签的值(对于 type 为 submit 类型来说,value 就对应了按钮上显示的文本)
- input 标签的内容:表示 query string 的 value
通过 ajax 构造 HTTP 请求
还可以通过 ajax 的⽅式来构造HTTP请求.并且功能更强⼤
HTTPS
是在HTTP协议的基础上引⼊了⼀个加密层(SSL). HTTP协议内容都是按照⽂本的⽅式明⽂传输的.这就导致在传输过程中出现⼀些被篡改的情况,比如说我们常常在浏览器下载软件的时候明明下的不是这个软件可是下载完就变了,这就是篡改了下载的地址信息。
因此在互联网上明文传输是一件非常可怕的事情。因此要在HTTP基础上进行加密。
加密"是什么
加密就是把明⽂(要传输的信息)进⾏⼀系列变换,⽣成密⽂. 解密就是把密⽂再进⾏⼀系列变换,还原成明⽂。在这个加密和解密的过程中,往往需要⼀个或者多个中间的数据,辅助进⾏这个过程,这样的数据称为密钥。
加密的⽅式
对称加密
对称加密其实就是通过同⼀个"密钥",把明⽂加密成密⽂,并且也能把密⽂解密成明⽂。使用单一密钥,计算量相对较小,适合对大量数据进行加密处理,能高效地完成加密和解密操作。但是每个服务端需要去对于多个客服端,都是用一个密钥的话,就会很容易窃取到该密钥并进行篡改。因此我们针对不同的客户端要采用不同的密钥。
非对称加密
非对称加密使用一对密钥,即公钥和私钥。公钥可以公开,任何人都可以使用公钥对数据进行加密;而私钥则由用户自己秘密保存,只有拥有私钥的人才能对使用相应公钥加密的数据进行解密。当发送方要向接收方传输数据时,发送方使用接收方的公钥对明文进行加密,然后将密文发送给接收方。接收方收到密文后,使用自己的私钥进行解密,恢复出原始明文。相比对称加密,非对称加密的计算量较大,加密和解密过程需要更多的时间和计算资源。因此,它不太适合对大量数据进行直接加密。
但是这里依然存在问题,我们如何获取公钥呢获取公钥如何判断这个公钥是不是黑客伪造的呢。
中间⼈攻击
中间人攻击是一种网络攻击手段,攻击者在通信双方不知情的情况下,拦截、篡改或伪造通信数据。攻击者处于通信双方之间,就像一个 “中间人”,分别与发送方和接收方建立看似正常的连接,使得双方误以为是在直接通信,但实际上所有的数据都经过了攻击者的处理。
具体流程如下:
- 服务器具有⾮对称加密算法的公钥S,私钥S'
- 中间⼈具有⾮对称加密算法的公钥M,私钥M'
- 客⼾端向服务器发起请求,服务器明⽂传送公钥S给客⼾端
- 中间⼈劫持数据报⽂,提取公钥S并保存好,然后将被劫持报⽂中的公钥S替换成为⾃⼰的公钥M, 并将伪造报⽂发给客⼾端
- 客⼾端收到报⽂,提取公钥M(⾃⼰当然不知道公钥被更换过了),⾃⼰形成对称秘钥X,⽤公钥M加 密X,形成报⽂发送给服务器
- 中间⼈劫持后,直接⽤⾃⼰的私钥M'进⾏解密,得到通信秘钥X,再⽤曾经保存的服务端公钥S加 密后,将报⽂推送给服务器
- 服务器拿到报⽂,⽤⾃⼰的私钥S'解密,得到通信秘钥X
- 双⽅开始采⽤X进⾏对称加密,进⾏通信。但是⼀切都在中间⼈的掌握中,劫持数据,进⾏窃听甚 ⾄修改,都是可以的
证书
服务端在使⽤HTTPS前,需要向CA机构申领⼀份数字证书,数字证书⾥含有证书申请者信息、公钥信 息等。服务器把证书传输给浏览器,浏览器从证书⾥获取公钥就⾏了,证书就如⾝份证,证明服务端 公钥的权威性
工作原理
身份验证:以网站与用户通信为例,当用户访问网站时,网站将数字证书发送给用户浏览器。浏览器内置众多受信任 CA 的根证书,通过这些根证书验证网站证书的 CA 签名。若签名验证成功,且证书其他信息(如有效期、主体名称与访问域名匹配等)无误,浏览器确认网站身份合法,建立安全连接。
数据加密:在建立安全连接过程中,基于证书中的公钥实现密钥交换。例如在 SSL/TLS 握手阶段,客户端生成随机的预主密钥,用网站证书中的公钥加密后发送给网站。网站用私钥解密获取预主密钥,双方据此生成会话密钥,用于后续通信数据的加密和解密,保证数据传输的保密性。
完整性保护:数字证书结合哈希算法和数字签名保证数据完整性。发送方对数据计算哈希值,用私钥对哈希值签名。接收方收到数据和签名后,重新计算数据的哈希值,并用发送方公钥验证签名。若验证通过,说明数据在传输过程中未被篡改。