应用场景选择
如果需要可靠传输,首选 TCP
如果需要传输的数据包很大,也首选 TCP
绝大部分的场景,都可以优先考虑 TCP
UDP 相比于 TCP,最大的优点在于传输效率
有些情况,既需要可靠性又需要性能,这个时候时候就需要 KCP
TCP 是高可靠低效率,UDP 是无可靠高效率,KCP 是低可靠较高效率
如何使用 UDP 来实现可靠传输?
TCP 咋做我们就咋做
IP 协议主要完成的工作是两方面
1.地址管理,使用一套地址体系,来描述互联网上每个设备所处的位置
2.路由选择
先认识一下 IP 协议报头
上述拆包过程都是 IP(系统内核)自动完成的(IP 的拆包并不是因为达到 64 KB,而是在数据链路层还有限制)
包拆了之后,未来如何组包?
六度空间理论
世界上任何两个人想认识一下,只需要六层朋友介绍(设想是每个人执行力都是一定的)
在计算机中,每个路由器都是“执行力最强的朋友”
所以想要通过网络访问到世界任何一个角落,最多经历 32 / 64 次就足够了
windous 有一个命令 tracert 这个命令就可以看到当前网络通信的路径是怎样的
IP 协议如何管理的地址?
IP 地址本质上就是一个 32 整数,为了方便,就会把 IP 表示成 点分十进制 的方式,通过 3 个点分成 4 个部分,每个部分 1 个字节,每个部分的取值都是 0 - 255
IP 地址存在,目的就是为了能够区分网络上不同的设备,希望每个网络设备都有唯一的一个 IP 地址
如何解决 IP地址不够用?
1.动态分配 IP 地址
2.NAT地址
先把 IP 分成两大类
1.私网 IP / 局域网 IP
IP 地址是以 10.*,172.16-172.31.*,192.168.*
这三类地址都是 私网 IP
2.公网IP / 广域网 IP
要求公网上的设备,对应的公网 IP,都必须是唯一的
但是私网上 / 局域网上的设备,使用私网 IP,只要保证局域网内部的 IP 不重复即可,不同的局域网之间的 IP 允许重复
由于上述设定,就有一个重要的限制:
1.公网设备访问公网设备,没有任何问题,直接访问即可
2.局域网设备访问局域网设备(同一个局域网),也没有问题
3.局域网设备访问局域网设备(不同局域网),不允许访问
4.局域网设备访问公网设备,就需要对局域网设备的 IP 进行地址转换
5.公网设备访问局域网设备,不允许主动访问
3.IPV6
增加了 IP 地址个数
IPV4 使用了 4 个字节表示 IP 地址
IPV6 使用了 16 个字节 表示 IP 地址
IPV6 和 IPV4 不兼容
把一个 IP 地址,分成两个部分,网络号 + 主机号
我们的机器都是在一个局域网中的,网络号都是相同的,主机号是不同的
一个局域网中,网络号 和 主机号 都相同,是无法上网的
如果局域网中的设备,网络号 和 路由器的网络号不相同,无法上网
路由器 有一个功能 DHCP 自动把局域网这里的设备的 IP 分配好
1111 1111 1111 1111 1111 1111 0000 0000
左侧全都是 1, 右侧全是 0,不会出现 1 0 混着,位置为 1的扑粉都是“网络号”,为 0 的部分就全都是主机号
家用宽带来说的话,一般默认前三个字节是网络号,主机号的范围就表示局域网中可以有多少个设备,一个字节能表示 256
时间往前推移 20 到 30 年左右,当年的网段划分方式不太一样
在之前的网段划分方式,没有子网掩码,直接通过设定 IP 的前缀来起到设置网段的效果
比较死板,尤其是 A B 类浪费了 很多 IP 地址
一些特殊的 IP地址
127.0.0.1 127.* 环回 IP
如果某个 IP 的主机号为全 0,表示 “这个网段” 它不能分配给某个主机
如果某个 IP 的主机号全是 1,表示“广播地址” ,表示二进制全是 1
192.168.0.255 这才是正确的
广播一对多,这样的传输,而且这里的多,指的是所有人
单播:一对一
组播:一对多(整体的一部分)
广播:一对多(整体的所有)
往广播地址上发消息,局域网中所有的设备都能收到,必须要发 UDP 的消息,TCP 不支持广播
广播的一个典型的应用场景:手机投屏 / 电脑投屏
点击投屏,手机就会在局域网中广播一个查询数据包,看哪些设备有回应,根据回应,就知道 IP
为哪个的设备是能够支持投屏的
接下来选择对应的设备,就可以把数据和这个设备进行通信了
IP 协议 地址管理
路由选择
网络结构太复杂,每个路由器都无法掌握全局的信息,只能掌握一部分局部信息,此时路由器规划出来的路线,只能是一个“较优解”
路由器转发数据包的过程就是类似的过程
数据报中包含了“目的 IP” 字段,就是要问路的目标,每个路由器都对于网络环境(和他相邻的设备情况)有一定了解的,此时,就可以根据它的了解告诉我们下一步往哪个方向走
路由器内部有一个数据结构,路由表
路由表 目的 IP 的网段 对应的网络接口(从路由器的哪个口出)
拿着目的 IP 去路由表匹配,很可能此时查询结果在路由表不存在
数据链路层
以太网(横跨数据链路层 和 物理层)
以太网
数据帧格式
数据链路层,引入了另外一套地址体系,称为“mac地址” / 物理地址
mac 地址 和 IP 地址 是独立的两套地址体系
IP 地址 侧重于 全局的转发,从起点到终点,这整个转发过程,通过 IP 地址 负责完成(查询路由表,通过 IP 地址)
MAC 地址,侧重于 局部的转发,两个相邻设备之间的转发
一般开发很少用到 mac 地址,而 IP 地址会用的很多
mac 地址通常按照 16 禁止的方式表示字节之间通常使用 - 或者 :分割
mac 地址表示的范围比 IPV4 地址大很多,当前 mac 地址都是和主机 一对一绑定的
IP 地址很多时候都是动态分配的
mac 地址就是静态分配的,网卡出厂时,mac 地址就写死了
由于 mac 地址有这样的特性,有些程序,就会使用 mac 地址来作为机器的身份标识
域名解析系统 DNS
使用 IP 地址来描述网络设备的位置 域名 一串可读性更好的单词 把域名自动的转换成对应的 IP 地址
上古时期,映入了一个 hosts 文件
这里的内容就是行文本,包含很多行,每一行都有 IP 和 域名,每次访问某个域名就会进行查询,获取到对应的 IP
hosts 文件目前仍然是有效的
搭建域名服务器的时候还会对于域名进行分级管理,一级域名,二级域名,三级域名。。。。这样就可以控制每个服务器管理的数据都不多
这时谷歌搞的一套 DNS 镜像服务器
HTTP 协议
HTTP 也是基于 TCP 来实现的
“超文本传输协议”
文本 => 字符串 超文本 不仅仅是字符串,还可以携带一些图片,特殊的格式
HTTP 协议最主要的应用场景,就是网站,浏览器 和 服务器之间,传输数据,客户端 和 服务器之间的数据传输,也很可能是 HTTP
HTTP 协议交互过程
HTTP 报文格式
抓包工具 抓包工具本质上是一个 “代理程序”,能够获取到网络上传输的数据,并显示出来
代理分成两种
正向代理(客户端代言人)
反向代理(服务器代言人)
如果之前fidder 安装配置没问题的话,会抓到很多数据包
打开一个网站,浏览器和服务器之间进行的 HTTP 交互不是只有一次,通常有很多次,第一次交互拿到这个页面的 html,html 还会依赖其他的 css 和 js,图片等,html 被浏览器加载之后,又会触发一些其他的 http 请求,获取到 css,js等,当执行js 的时候,js 代码里可能又要触发很多的http请求,获取到一些数据
蓝色的表示返回的是一个 html,往往是一个网站的入口请求,选中请求并双击,能看到明细
右上角请求明细
右下角响应明细
http请求的原始数据
当前响应数据被压缩了,网络传输中,带宽是一个比较贵的硬件资源,为了节省带宽,就可以把相应数据进行压缩
HTTP 请求,包含四个部分
1.首行
2.请求头
3.空行
请求头最下面会有一个空行,这个空行就可以表示结束标记
4.正文(body)
http 的载荷部分
有的 http 有 body 有的没有
HTTP 响应的基本格式,分成 4 个部分
1.首行
2.响应头 键值对
3.空行
4.响应正文
相应的载荷是 html
URL
描述一个网络上的资源位置
唯一资源定位符
uri 是唯一资源标识符
查询字符串,是客户端给服务器传递信息的重要途径,这里的组织方式是按照键值对的方式来组织的
关于 URL encode
query string 里是自定义的键值对
在 URL 中,本身有些特殊符号具有特定的含义
如果 url 的 query string 中也包含同样的符号,咋办?
如果直接写进去,可能就会使服务器 / 浏览器 解析失败,靠谱的方法就是对上述符号进行 “转义”
对于汉字,也是要进行转义的
汉字的 utf8 / gbk 等编码值其中可能某个字节就恰好和某可符号的 ascil 码一致
这里的 urlencode 编码十分重要
实际开发中,当要构造一个 url,尤其是 url 的 query string 中要包含中文的时候,务必要进行编码