软件工程师需要了解的网络知识:从铜线到HTTP(四)—— TCP 和路由器
基础梳理
- 截至目前,我们已经得到了三个首部:以太网首部、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 包可能还在路上,所以两个方向的 TCP 流是并行的,要单独分别断开连接。
路由器
严格意义的路由器是工作在网络层的设备,即 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 :
- 发送 ARP 请求得到网关的 MAC 地址
- 将数据包上 TCP 首部(目标端口 80,源端口 20000)、IP 首部(目标 ip 地址 114.114.114.114,源 ip 地址 192.168.1.2)、以太网首部(目标地址是 192.168.1.1 的 MAC 地址),发送给交换机
- 交换机会直接将这个包发到网关所在的网口上
-
网关收到了这个以太网帧,进行层层解包:
- 目标 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,发送到局域网交换机上,再由交换机进行以太网帧转发。
WAN 口、LAN 口
现代家用路由器一般有一个 WAN 口(广域网端口)和 4-8 个 LAN 口(局域网端口)。有多个 LAN 口本质上是集成了一个交换机。
NAT 服务器
网络地址转换:将一个公网 ip 直接映射到一个内网 ip 上,当 IP 包经过路由器时,路由器会修改里面的 来源 IP 地址和目的 IP 地址,让双方都以为自己真的是和对方直接连接的。
DNS 服务器
IP 网络中每一个网络终端都有一个 ip 地址,但是一串数字十分难记,于是域名便诞生了。路由器充当 DNS 服务器的目的是提升连接速度,节省局域网内设备的 DNS 查询时间。
DHCP 服务器
提供自动分配 IP 服务,免去手动设置 ip 地址、子网掩码、网关、DNS 服务器的烦恼,让网络实现真正的即开即用。
评论:
2018-01-30 17:56
2018-01-30 02:30
这句解开了我的疑惑,感谢!
2020-03-07 11:44
按两条通道理论,解释不了最后一个ACK啊,A收到B的FIN的ACK后,只有一个通道是B发给A的,A不能发送,