JohnLui:程序员,Swift Contributor,正在写《iOS 可视化编程与 Auto Layout》
基础梳理
截至目前,我们已经得到了三个首部:以太网首部、IP 首部、TCP 首部。
这三者看起来类似,实际却完全不同:
以太网首部是以太网技术提供的基础数据 package 功能:其数据包的长度是以太网独有的,和其他技术如光纤环网 FDDI 是完全不同的。实际上其他技术都不一定用的是 帧 这种基础逻辑单元,也不一定用的是这种简单的交换方式。
IP 是网络层协议,其存在的意义是规定一种跨物理实现的“虚拟网络”,让这个网络在上层看来是一致的。从这个意义上来讲,IP 层是 Internet 的本体。IP 网络是真正的全球统一的网络。每一台接入网络的计算机都有一个 ip 地址。
TCP 是传输层协议,其目的是在统一的 IP 层上实现“可靠”的信息传递。
可靠的 TCP
以太网数据帧和 IP 数据包都只是简单地规定了头部应该如何携带信息,而以太网帧并不保证能够送达,也不能保证按照顺序送达,出现了可靠性问题。
假设我们需要从 192.168.1.2 向 192.168.1.3 发送一首歌,这首歌是真正的二进制数据,全部采用 0、1 组成,这样会便于我们理解,因为人脑处理文本信息的时候总是有一种障碍。
在没有 TCP 协议的情况下,我们知道了本机以及目标计算机的 ip 地址,我们将歌曲的二进制信息按照 1500 字节(12000位)一块,分别包裹上 IP 首部和以太网首部,通过网口将这段 0、1 发送了出去。假设一共 2000 个 以太网帧。接着就会出现下面几种情况:
前 1000 个 以太网帧被交换机完美地转发过去了,但是后 1000 个因为交换机受到干扰而没有发到 192.168.1.3 那里,歌曲放到一半就放不出来了。
2000 个都发过去了,但是顺序错乱了:我们会得到一个放不出来的奇怪二进制文件。
2000 个都发过去了,但是部分数据遭到了破坏,0 变成了 1,结果歌曲放一半播放器崩溃了。
这时候我们就会发现只靠 IP 协议是无法满足所有通信要求的。
TCP 通过校验、序列号机制、确认应答机制、重发控制、连接管理等特性实现了可靠性传输。具体的特性不再展开叙述,因为 TCP 实在是太复杂,展开讲还能再写五个本文这么长的系列文章。下面我重点介绍 TCP 实现可靠传输的几个重点功能:
TCP 以 段 为基本单位发送数据,段的长度是在首次建立连接的时候双方约定好的。
序列号和确认应答机制:每个段的发送都会携带一个整数序列号:当前段第一位在完整数据中的字节顺序,每次接收到一个段,远程计算机都要回复一个带序列号的“确认收到”。
重发机制:首个段发送的时候使用一个比较大的 timeout 值,之后每次的 timeout 的值都是实时计算的,因为 TCP 希望在网络情况变化时也能够尽可能地提供高性能的传输。timeout 时间过了还没有收到携带本段序列号的“确认收到”,那就重发。
TCP 还有基于窗口的发送速度优化、流量控制、拥塞控制等内容不再赘述。
三次握手和四次挥手## 三次握手
为了建立一个可靠的 TCP 连接,客户端和服务端之间需要进行三次数据发送:
客户端:我要建立连接。
服务端:收到。我也要建立连接。
客户端:收到。
经历过这三个 IP 包的来往,这个可靠的 TCP 连接才算建立成功了。
同上,经过这四次 IP 包的往来,双方都认为这个 TCP 连接已经断开了,相应的内存资源就可以释放了。
原因很简单:TCP 是全双工协议,即可以同时发送和接收数据,两条通道是完全独立的。
尝试建立连接时,两者之间什么关系都没有,而“收到。我也要建立连接。”这两个动作是有顺序的,直接用一个 IP 包发送就可以了,节省时间。
尝试断开连接时,“收到。我也要断开连接。”这两个动作之间还有其他事情要发生:客户端这边是不会再发送数据了,但是服务器发给客户端的 IP 包可能还在路上,这时候就要等待客户端给一个“收到”的回应,才能放心地发出“我也要断开连接”这个包。
路由器
严格意义的路由器是工作在网络层的设备,即 IP 层。但是现代以太网路由器都是 路由器、网关、NAT 服务器、DNS 服务器、DHCP 服务器 的结合体,不少路由器还有防火墙功能。下面我将分开解释这几种功能。
Router 本质是一种“智能”设备,其会为经过它的每一个数据帧寻找一条最佳传输路径,以将该数据最有效地传送到目的站点。Internet 是网状的,而且是动态的,所以路由器是一种非常重要的设备,可以说是它保持了 Internet 的高性能。
Gateway 是用于两个不同类型的网络之间通信的设备,例如实现两个以太网的相互通信,实现家庭以太网中的所有设备和光纤背后的服务器的通信。在实际场景中,网关将实现一个重要功能:沟通局域网中的设备和公网设备,例如让 192.168.1.2 这台计算机能够从 baidu.com 的服务器下载网页显示到浏览器上。
一台计算机所拥有的 ip 地址和子网掩码配合,让这台计算机认识到了自己的局域网的范围在哪儿。我们采用家用网络中最常见的 192.168.1.2/255.255.255.0 的配合来解释它的作用:
192.168.1.2 是本机的 ip,也是判定某个 ip 是不是局域网 ip 的基础
255.255.255.0 的意思是前三段保持一致,最后一段 0-255 都是局域网 ip
换句话说就是 192.168.1.0 - 192.168.1.255 都是和本机一个局域网的计算机
那判断目标 ip 是不是同一个局域网有什么用呢?
如果要连接的是局域网内的 192.168.1.3,那么连接方式将是:
发送 ARP 请求得到该 ip 地址对应的 MAC 地址
将数据包上 TCP 首部、IP 首部(目标 ip 地址 192.168.1.3)、以太网首部(目标地址是 192.168.1.3 的 MAC 地址),发送给交换机
交换机会直接将这个包发到目标计算机所在的网口上
如果要连接的是 114.114.114.114 这个 ip,那么本机就会将这个包发给网关 192.168.1.1 :
目标 MAC 地址是自己,说明这个包是合法的
IP 首部中的目标 ip 地址不是自己,说明这是一个需要网关进行转发的数据包,接着进入转发流程:
TCP 首部中,目标端口 80 不会变,但是源端口 20000 指的是 192.168.1.2 这台计算机的源端口,在网关 192.168.1.1 上这个端口已经被别的局域网机器用过了,该怎么办?修改端口
将 TCP 首部中的源端口改为 50000,将 IP 首部中的源 ip 地址改为本路由器的 WAN 口 ip,即公网 ip,发送出去。我们假设本路由器的公网 ip 为 106.0.0.1。
此时网关设备的内存里已经建立起了一个映射:50000 端口对应的是内网的 192.168.1.2 的 20000 端口,当来自 114.114.114.114 80 端口的 IP 包到达时,同样将目标 ip 地址从 106.0.0.1 改为 192.168.1.2,目标端口 从 50000 改为 20000,发送到局域网交换机上,再由交换机进行以太网帧转发。
发送 ARP 请求得到网关的 MAC 地址
将数据包上 TCP 首部(目标端口 80,源端口 20000)、IP 首部(目标 ip 地址 114.114.114.114,源 ip 地址 192.168.1.2)、以太网首部(目标地址是 192.168.1.1 的 MAC 地址),发送给交换机
交换机会直接将这个包发到网关所在的网口上
网关收到了这个以太网帧,进行层层解包:
现代家用路由器一般有一个 WAN 口(广域网端口)和 4-8 个 LAN 口(局域网端口)。有多个 LAN 口本质上是集成了一个交换机。
网络地址转换:将一个公网 ip 直接映射到一个内网 ip 上,当 IP 包经过路由器时,路由器会修改里面的 来源 IP 地址和目的 IP 地址,让双方都以为自己真的是和对方直接连接的。
IP 网络中每一个网络终端都有一个 ip 地址,但是一串数字十分难记,于是域名便诞生了。路由器充当 DNS 服务器的目的是提升连接速度,节省局域网内设备的 DNS 查询时间。
提供自动分配 IP 服务,免去手动设置 ip 地址、子网掩码、网关、DNS 服务器的烦恼,让网络实现真正的即开即用。
目前5000+人已关注加入我们
目前5000+人已关注加入我们
前端路上的益友