网络协议系列文章
网络协议(一):基本概念、计算机之间的连接方式
网络协议(二):MAC地址、IP地址、子网掩码、子网和超网
网络协议(三):路由器原理及数据包传输过程
网络协议(四):网络分类、ISP、上网方式、公网私网、NAT
网络协议(五):网络互联模型、物理层、数据链路层
网络协议(六):网络层(版本、首部长度、区分服务、总长度、 标识、标志、片偏移生存时间、协议、首部校验和)
网络协议(七):传输层-UDP
网络协议(八):传输层-TCP(可靠性传输、拥塞控制、建立连接-三次握手、释放连接-四次挥手)
网络协议(九):应用层(域名、DNS、DHCP)
网络协议(十):HTTP(报文格式、请求方法、头部字段、状态码、跨域)
网络协议(十一):单向散列函数、对称加密、非对称加密、混合密码系统、数字签名、证书
网络协议(十二):HTTPS(SSL/TLS、TLS1.2的连接)
网络协议(十三):HTTP/1.1的升级改进(HTTP/2、HTTP/3)
网络协议(十四):WebSocket、WebService、RESTful、IPv6、网络爬虫、HTTP缓存
目录
- 一、WebSocket
- 二、WebService
- 三、RESTful
- 四、IPv6
- 五、网络爬虫
- 六、HTTP 缓存(Cache)
一、WebSocket
- Socket 是一套网络编程API,利用它可以建立网络连接,一般都是操作系统底层实现的
- WebSocket 是一个网络协议
- HTTP请求的特点:通信只能由客户端发起。所以,早期很多网站为了实现推送技术,所用的技术都是轮询
- 轮询:由浏览器每隔一段时间(如每秒)向服务器发出HTTP请求,然后服务器返回最新的数据给客户端
- 为了能更好的节省服务器资源和带宽,并且能够更实时地进行通讯,HTML5规范中出现了WebSocket协议
WebSocket,是基于TCP的支持全双工通信的应用层协议
- 在2011年由IETF标准化为 RFC 6455,后由 RFC 7936 补充规范
- 客户端、服务器,任何一方都可以主动发消息给对方
- WebSocket 的应用场景很多
- 社交订阅、股票基金报价、体育实况更新、多媒体聊天、多玩家游戏等
- WebSocket 和 HTTP 属于平级关系,都是应用层的协议
- 其实TCP本身就是支持全双工通信的(客户端、服务器均可主动发消息给对方)
- 只是HTTP的 “请求-应答模式” 限制了TCP的能力
- WebSocket 使用 80(ws://)、443(wss://) 端口,可以绕过大多数防火墙的限制
- ws://example.com/wsapi
- wss://secure.example.com/wsapi
- 与 HTTP 不同的是,WebSocket 需要先建立连接
- 这就使得WebSocket成为一种有状态的协议,之后通信时可以省略部分状态信息
- 而HTTP请求可能需要在每个请求都额外携带状态信息(如身份认证等)
WebSocket 使用
- WebSocket 体验和演示:https://www.websocket.org/echo.html
- W3C 标准化了一套 WebSocket API,可以直接使用JS调用:
- let ws = new WebSocket(‘wss://example.com’)
WebSocket - 建立连接
- WebSocket 需要借助 HTTP协议来建立连接(也叫作握手,Handshake)
- 由客户端(浏览器)主动发出握手请求
二、WebService
- WebService,译为:Web服务,是一种跨编程语言和跨操作系统的远程调用技术标准
- 其实 WebService 是比较老的技术,放到现在已经可以由普通的 Web API 取代
- WebService使用场景举例
- 天气预报、手机归属地查询、航班信息查询、物流信息查询等
- 比如天气预报,是气象局把自己的服务以WebService形式暴露出来,让第三方程序可以调用这些服务功能
- http://www.webxml.com.cn/zh_cn/index.aspx
- 事实上,WebService完全可以用普通的 Web API 取代(比如HTTP + JSON)
SOAP (Simple Object Access Protocol),译为:简单对象访问协议
- 很多时候,SOAP = HTTP + XML
- WebService 使用 SOAP协议 来封装传递数据
WSDL (Web Services Description Language),译为:Web服务描述语言
- 一个XML文档,用以描述WebService接口的细节(比如参数、返回值等)
- 一般在WebService的URL后面跟上 ?wsdl 获取WSDL信息
- http://ws.webxml.com.cn/WebServices/WeatherWS.asmx?wsdl
三、RESTful
- REST (REpresentational State Transfer),表现层状态转移
- REST是一种互联网软件架构设计风格
- 定义了一组用于创建Web服务的约束
- 符合REST架构的Web服务,称为RESTful Web服务
RESTful 的实践建议
- URL中使用名词(建议用复数形式),不使用动词
- 推荐:/users、/users/6
- 不推荐:listsers、/getser?id=6,/uer/list、/user/get?id=6
- 使用 HTTP的请求方法 表达动作:
- 一个资源连接到其他资源,使用子资源的形式
- GET /users/6/cars/8
- POST /users/8/cars
- API 版本化
- mj.com/v1/users
- mj.com/v2/users/66
- 返回 JSON格式的数据
四、IPv6
- IPv6 (Internet Protocol version 6),网际协议第6版
- 用它来取代IPv4主要是为了解决IPv4地址枯竭问题,同时它也在其他方面对于IPv4有许多改进
- 然而长期以来IPv4在互联网流量中仍占据主要地位,IPv6的使用增长缓慢
- 在2019年12月,通过IPv6使用Google服务的用户百分率首次超过30%
- 因为使用IPv6需要设备、操作系统内核升级支持IPv6,不像HTTP升级到HTTP2一样方便
- IPv6采用128位的地址,而IPv4使用的是32位
- 支持2^128(约3.4 ∗ 10^38 )个地址
- 以地球人口70亿人计算,每人平均可分得约 4.86 ∗ 10^28个IPv6地址
- 解决了IPv4地址枯竭问题
IPv6 - 地址格式
- IPv6地址为128bit,每16bit一组,共8组
- 每组以冒号 : 隔开,每组以4位十六进制方式表示
- 例如 2001:0db8:86a3:08d3:1319:8a2e:0370:7344
- 类似于IPv4的点分十进制,IPv6同样也存在点分十六进制的写法
- 2.0.0.1.0.d.b.8.8.5.a.3.0.8.d.3.1.3.1.9.8.a.2.e.0.3.7.0.7.3.4.4
- 每组前面连续的0可以省略。下列IPv6地址是等价的:
- 2001:0db8:02de:0000:0000:0000:0000:0e13
- 2001:db8:2de:0:0:0:0:e13
- 双冒号 :: 表示一组0或多组连续的0,但只能出现一次。下列IPv6地址等价:
- 2001:db8:2de:0:0:0:0:e13
- 2001:db8:2de::e13
- 2001::25de::cade 是非法的,因为双冒号:出现了两次,会造成歧义
- 2001:0000:0000:0000:0000:25de:0000:cade
- 2001:0000:25de:0000:0000:0000:0000:cade
- ::1是本地环回地址:0:0:0:0:0:0:0:1
- ping ::1 可以ping通本机
IPv6 - 首部格式
- IPv6 有40字节的固定首部
- Version (占4bit,0110):版本号
- Traffic Class (占8bit):交通类别
- 指示数据包的类别或优先级,可以帮助路由器根据数据包的优先级处理流量
- 如果路由器发生拥塞,则优先级最低的数据包将被丢弃
- Payload Length (占16bit):有效负载长度
- 最大值65535字节
- 包括了扩展头部、上层(传输层)数据的长度首部格式
- Hop Limit (占8bit):跳数限制
- 与IPv4数据包中的TTL相同
- Source Address (占128bit):源IPv6地址
- Destination Address (占128bit):目的IPv6地址
- Flow Label (占20bit):流标签
- 指示数据包属于哪个特定序列(流)
- 用数据包的源地址、目的地址、流标签标识一个流
IPv6 - 拓展头部
- Next Header(占8bit):下一个头部
- 指示扩展头部(如果存在)的类型、上层数据包的协议类型(例如TCP、UDP、ICMPv6)
五、网络爬虫
- 网络爬虫 (Web Crawler),也叫做网络蜘蛛 (Web Spider)
- 模拟人类使用浏览器操作页面的行为,对页面进行相关的操作
- 常用爬虫工具:Python 的 Scrapy框架
网络爬虫的简易实例
- 爬虫目标:https://ext.se.360.cn/webstore/categor
import org.apache.commons.io.FileUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import java.io.File;
import java.net.URL;
public class Main {
public static void main(String[] args) throws Exception {
// 请求网站:https://ext.se.360.cn/webstore/category
// Jsoup使用CSS选择器来查找元素
String dir = "C:/Users/yusael/Desktop/imgs/"; // 爬取后的存放路径
String url = "https://ext.se.360.cn/webstore/category";
Document doc = Jsoup.connect(url).get();
Elements eles = doc.select(".applist .appwrap");
for (Element ele : eles) {
String img = ele.selectFirst("img").attr("src");
String title = ele.selectFirst("h3").text();
String intro = ele.selectFirst(".intro").text();
// 下载图片
String filepath = dir + (title + ".png");
FileUtils.copyURLToFile(new URL(img), new File(filepath));
}
}
}
robots.txt
- robots.txt 是存放于网站根目录下的文本文件,比如 https://www.baidu.com/robots.txt
- 用来告诉爬虫:哪些内容是不应被爬取的,哪些是可以被爬取的
- 因为一些系统中的URL是大小写敏感的,所以 robots.txt 的文件名应统一为小写
- robots.txt 并不是一个规范,而只是约定俗成的,所以并不能保证网站的隐私
- 只能防君子,不能防小人
- 无法阻止不讲 “武德” 的年轻爬虫爬取隐私信息
六、HTTP 缓存(Cache)
- 实际上,HTTP 的缓存机制远远比上图的流程要复杂
- 通常会缓存的情况是:GET请求 + 静态资源(比如HTML、CSS、JS、图片等)
- Ctrl + F5:可以强制刷新缓存
缓存 - 响应头
- Pragma:作用类似于Cache-Control,HTTP/1.0的产物
- Expires:缓存的过期时间 (GMT格式时间),HTTP/1.0的产物
- 在http协议中规定,所有时间都要转换为GMT时间,例如date: Sat, 19 May 2018 17:17:24 GMT
- Cache-Control:设置缓存策略
- no-storage:不缓存数据到本地
- public:允许用户、代理服务器缓存数据到本地
- private:只允许用户缓存数据到本地
- max-age:缓存的有效时间(多长时间不过期),单位秒
- no-cache:每次需要发请求给服务器询问缓存是否有变化,再来决定如何使用缓存
优先级:Pragma > Cache-Control > Expires
- Last-Modified:资源的最后一次修改时间
- ETag:资源的唯一标识(根据文件内容计算出来的摘要值)
优先级:ETag > Last-Modifie
缓存 - 请求头
- If-None-Match
- 如果上一次的响应头中有ETag,就会将ETag的值作为请求头的值
- 服务器发现资源的最新摘要值跟If-None-Match不匹配,就会返回新的资源 (200 OK)
- 否则,就不会返回资源的具体数据 (304 Not Modified)
- If-Modified-Since
- 如果上一次的响应头中没有ETag,有Last-Modified,就会将Last-Modified的值作为请求头的值
- 如果服务器发现资源的最后一次修改时间晚于If-Modified-Since,就会返回新的资源 (200 OK)
- 否则,就不会返回资源的具体数据 (304 Not Modified)
- Last-Modified 缺陷
- 只能精确到秒级别,如果资源在1秒内被修改了,客户端将无法获取最新的资源数据
- 如果某些资源被修改了(最后一次修改时间发生了变化),但是内容并没有任何变化
(比如在文本中敲个空格再删除)会导致相同数据重复传输,没有使用到缓存
- ETag 可以办到
- 只要资源的内容没有变化,就不会重复传输资源数据
- 只要资源的内容发生了变化,就会返回最新的资源数据给客户端
缓存的使用流程