OSI 标准模型和 TCP/IP 协议模型
OSI(Open System Interconnection,开放式通信互联) 是由 ISO(International Organization for Standardization,国际标准化组织) 制定的标准模型。旨在将世界各地的各种计算机互联。然而,OSI 模型过于庞大、复杂。参照此模型,技术人员开发了 TCP/IP 协议栈,简化 OSI 七层模型为 TCP/IP 四层模型。获得了更广泛的使用。
OSI 模型和 TCP/IP 模型对比:
从上图可以看到,TCP/IP 模型合并了 OSI 模型的应用层、表示层和会话层,将 OSI 模型的数据链路层和物理层合并为网络访问层。
上图还列出了各层模型对应TCP/IP协议栈中的协议以及各层协议之间的关系。比如 DNS 协议是建立在 TCP 和 UDP 协议的基础上,FTP、HTTP、TELNET 协议建立在 TCP 协议的基础上,NTP、TFTP、SNMP 建立在 UDP 协议的基础上,而 TCP、UDP 协议又建立在 IP 协议的基础上,以此类推…..
TCP/IP 四层模型的意义
数据在网络中传输最终一定是通过物理介质传输。物理介质就是把电脑连接起来的物理手段,常见的有光纤、双绞线,以及无线电波,它决定了电信号(0和1)的传输方式,物理介质的不同决定了电信号的传输带宽、速率、传输距离以及抗干扰性等等。网络数据传输就像快递邮寄,数据就是快件。只有路打通了,你的”快递”才能送到,因此物理介质是网络通信的基石。
寄快递首先得称重、确认体积(确认数据大小),贵重物品还得层层包裹填充物确保安全,封装,然后填写发件地址(源主机地址)和收件地址(目标主机地址),确认快递方式。对于偏远地区,快递不能直达,还需要中途转发。网络通信也是一样的道理,只不过把这些步骤都规定成了各种协议。
TCP/IP的模型的每一层都需要下一层所提供的协议来完成自己的目的。因为我们平常只需要关注应用层,下层的操作我们不需要关心,而且网络协议体系本身庞大复杂,TCP/IP 的原理就一直云里雾里的。但是本质还是传输数据(送快递)。我们就来看下数据是怎么通过 TCP/IP 协议模型从一台主机发送到另一台主机的。
当用户通过 HTTP 协议发起一个请求,应用层、传输层、网络互联层和网络访问层的相关协议依次对该请求进行包装并携带对应的首部,最终在网络访问层生成以太网数据包,以太网数据包通过物理介质传输给对方主机,对方接收到数据包以后,然后再一层一层采用对应的协议进行拆包,最后把应用层数据交给应用程序处理。下面说每一层的含义。
网络访问层(host-to-network)
又称为链路层,是网络通信协议的最底层协议。通过物理介质只能传送 0 和 1 的电信号,单纯发送一堆 01 的数列是没有意义的,所以就需要对数列进行分组,并为每组电信号标识好信息特征(哪些位代表哪些含义),按照分组的顺序依次发送电信号。以太网规定一组电信号就是一个数据包,一个数据包就称为一帧,类似的这些规则就是以太网协议。完整的以太网数据包如下所示。
前 14 个字节是首部,包含源 MAC 地址、目标 MAC 地址和类型,最后四个字节是数据帧校验序列,确定数据包在传输过程中是否损坏。中间的就是要传输的数据。最少 46 个字节,最多 1500 个字节,如果要传输的数据过大就要分多个数据帧传送了。那么以太网是怎么把数据传给目标主机的呢?
以太网协议规定通过 MAC 地址来识别传输双方的身份,接入网络的设备必须安装网络适配器(网卡),数据包只能从一块网卡传输到另一个网卡,网卡地址就是 MAC 地址,是每块网卡的身份标识,全球唯一。MAC 地址是十六进制的,一共 6 个字节(48位)。前三个字节是厂商编号,后三个字节是网卡流水号。例如4C-0F-6E-12-D2-19
。有了 MAC 地址,以太网以广播的形式,把数据包发送给子网内的所有主机,主机接到数据包后检查首部中的目标 MAC 地址是不是自己,如果是自己就做进一步的处理,反之就会把包丢弃。
因此网络访问层的主要工作就是将电信号分组,然后将每组电信号封装成有特定意义的数据帧,以广播的形式通过物理介质发送给目标主机。
网络互联层
又称网络层,我们知道网络访问层的以太网协议会把数据包发送给子网内的所有主机,数据帧中包含 MAC 地址。但是 MAC 地址只与厂商有关,和所处于的网络无关,通过 MAC 地址没有办法判定两台主机是不是在同一个子网。那么它怎么知道哪些主机和它在同一个子网?要是目标主机不在同一个子网又怎么把数据传给它?
为了解决第一个问题,网络互联层引入 IP 协议。IP 协议制定一套新的 IP 地址,使得我们能够区分两台主机是不是处于同一个网络。
IP 地址目前分两个版本,就是我们常说的 IPV4 和 IPV6。IPV4 是 32 位地址,分四段(10.4.121.79),一段 8 位(最大 255),常用四个 10 进制的数字表示。IP 协议把这个 32 位的 IP 地址分两部分,第一部分表示网络地址,第二部分表示该主机在局域网中的地址。这就是 IP 的子网划分。
IP协议将子网划分为3类。
- A 类 IP 段
1.0.0.0
到126.255.255.255
(0 段 和 127 段不使用)。默认子网掩码255.0.0.0
,一个子网最多可以容纳 1658 万多台电脑。 - B 类 IP 段
128.0.0.0
到191.255.255.255
。默认子网掩码255.255.0.0
一个子网最多可以容纳 6 万台电脑。 - C 类 IP 段
192.0.0.0
到223.255.255.255
。默认子网掩码255.255.255.0
一个子网最多可以容纳 254 台电脑。
将 IP 地址和子网掩码转换成 2 进制的 32 位数字。例如 C 类 IP 192.160.4.1
。其子网掩码二进制为11111111.11111111.11111111.00000000
,进行逻辑与(&)操作,得到网络 ID 为192.160.4.0
。如果两个 IP 地址的网络 ID 相同,就说明他们在同一个子网中。
要算一个子网掩码最多可以容纳多少个电脑就可以这么算。例如子网掩码255.255.248.0
转换成二进制11111111.1111111.11111000.00000000
,后面有 11 个 0,就可以容纳 \( 2^{11} - 2 \) 台主机。减 2 是因为0.0.0.0
(全 0)是保留地址,255.255.255.255
(全 1)是广播地址。
算主机的子网中的主机 ID,将子网掩码取反。00000000.00000000.00000000.11111111
和 IP 做逻辑与(&)操作。得出的就是主机在该子网中的主机 ID。
应用层的协议会将发送者和接受者的IP地址传给网络互联层,因此通过子网掩码和 IP 进行逻辑与(&)就可以判断两个 IP 是不是同一个子网中。如果不在同一个子网中,就需要路由器转发才能进行数据交换。
当判断 IP 处于同一个子网中时,网络互联层通过 ARP(地址解析)协议根据 IP 地址获取 MAC 地址。ARP 首先会发起一个请求数据包,数据包的首部包含了目标主机的 IP 地址,然后这个数据包会在链路层进行再次包装,生成以太网数据包,最终由以太网广播给子网内的所有主机,每一台主机都会接收到这个数据包,并取出标头里的 IP 地址,然后和自己的 IP 地址进行比较,如果相同就返回自己的 MAC 地址,如果不同就丢弃该数据包。ARP 接收返回消息,以此确定目标机的 MAC 地址;与此同时,ARP 还会将返回的 MAC 地址与对应的 IP 地址存入本机 ARP 缓存中并保留一定时间,下次请求时直接查询 ARP 缓存以节约资源。cmd输入arp -a
就可以查询本机缓存的 ARP 数据。
通过 ARP 协议的工作原理可以发现,ARP 的 MAC 寻址还是局限在同一个子网中,因此网络互联层引入了路由协议,首先通过IP协议来判断两台主机是否在同一个子网中,如果在同一个子网,就通过 ARP 协议查询对应的 MAC 地址,然后以广播的形式向该子网内的主机发送数据包;如果不在同一个子网,以太网会将该数据包转发给本子网的网关(路由器)进行路由。网关是互联网上子网与子网之间的桥梁,所以网关会进行多次转发,最终将该数据包转发到目标 IP 所在的子网中,然后再通过 ARP 获取目标机 MAC,最终也是通过广播形式将数据包发送给接收方。
而完成这个路由协议的物理设备就是路由器(或者有路由功能的设备,比如开启了路由协议的服务器、代理服务器也可以称之为路由器),网关的 IP 地址就是具有路由功能的设备的 IP 地址。在错综复杂的网络世界里,路由器扮演者交通枢纽的角色,它会根据信道情况,选择并设定路由,以最佳路径来转发数据包。在网络互联层被包装的数据包就叫 IP 数据包,IPv4 数据包的结构如下图所示:
IP 数据包由首部和数据两部分组成,首部长度为 20 个字节,主要包含了目标 IP 地址和源 IP 地址,目标IP地址是网关路由的线索和依据;数据部分的最大长度为 65515 字节,理论上一个 IP 数据包的总长度可以达到 65535 个字节,而以太网数据包的最大长度是 1500 个字符,如果超过这个大小,就需要对 IP 数据包进行分割,分成多帧发送。
所以,网络层的主要工作是定义网络地址,区分网段,子网内MAC寻址,对于不同子网的数据包进行路由。
传输层
网络访问层的以太网协议规定通过MAC地址来识别传输双方的身份,而网络互联层定义了 IP 地址,明确了主机所在的网段,有了这两个地址,数据包就从可以从一个主机发送到另一台主机。但实际上数据包是从一个主机的某个应用程序发出,然后由对方主机的应用程序接收。而每台电脑都有可能同时运行着很多个应用程序,所以当数据包被发送到主机上以后,是无法确定哪个应用程序要接收这个包。因此传输层引入了 UDP 协议来解决这个问题,为了给每个应用程序标识身份,UDP 协议定义了端口,同一个主机上的每个应用程序都需要指定唯一的端口号,并且规定网络中传输的数据包必须加上端口信息。 这样,当数据包到达主机以后,就可以根据端口号找到对应的应用程序了。UDP 定义的数据包就叫做 UDP 数据包,结构如下所示:
UDP(User Data Protocol,用户数据报协议)
- UDP 是一个非连接的协议,传输数据之前源端和终端不建立连接,当它想传送时就简单地去抓取来自应用程序的数据,并尽可能快地把它扔到网络上。在发送端,UDP 传送数据的速度仅仅是受应用程序生成数据的速度、计算机的能力和传输带宽的限制;在接收端,UDP 把每个消息段放在队列中,应用程序每次从队列中读一个消息段。
- 由于传输数据不建立连接,因此也就不需要维护连接状态,包括收发状态等,因此一台服务机可同时向多个客户机传输相同的消息。
- UDP 信息包的标题很短,只有 8 个字节,主要包括源端口和目标端口;数据最大为 65527 个字节,整个数据包的长度最大可达到 65535 个字节。相对于 TCP 的 20 个字节信息包的额外开销很小。
- 吞吐量不受拥挤控制算法的调节,只受应用软件生成数据的速率、传输带宽、源端和终端主机性能的限制。
- UDP 使用尽最大努力交付,即不保证可靠交付,因此主机不需要维持复杂的链接状态表(这里面有许多参数)。
- UDP 是面向报文的。发送方的 UDP 对应用程序交下来的报文,在添加首部后就向下交付给 IP 层。既不拆分,也不合并,而是保留这些报文的边界,因此,应用程序需要选择合适的报文大小。
我们经常使用ping
命令来测试两台主机之间 TCP/IP 通信是否正常,其实ping
命令的原理就是向对方主机发送 UDP 数据包,然后对方主机确认收到数据包,如果数据包是否到达的消息及时反馈回来,那么网络就是通的。
UDP 协议比较简单,实现容易,但它没有确认机制, 数据包一旦发出,无法知道对方是否收到,因此可靠性较差,为了解决这个问题,提高网络可靠性,TCP 协议就诞生了,TCP 即传输控制协议,是一种面向连接的、可靠的、基于字节流的通信协议。简单来说 TCP 就是有确认机制的 UDP 协议,每发出一个数据包都要求确认,如果有一个数据包丢失,就收不到确认,发送方就必须重发这个数据包。
为了保证传输的可靠性,TCP 协议在 UDP 基础之上建立了三次对话的确认机制,也就是说,在正式收发数据前,必须和对方建立可靠的连接。
名词解释:
- ACK TCP 报头的控制位之一,对数据进行确认。确认由目的端发出,用它来告诉发送端这个序列号之前的数据段都收到了。比如:确认号
ack=x
,则表示前x-1
个数据段都收到了。只有当ACK=1
时,确认号ack才有效,当ACK=0
时,确认号ack
无效,这时会要求重传数据,保证数据的完整性。 - SYN 同步序列号,TCP 建立连接时需要将
SYN
置为1,说明这是一个连接请求,或者连接接受报文。TCP 规定SYN=1
时不能携带数据,但要消耗一个序号seq
,因此需要声明自己的序号是什么,比如:seq=x
。 - FIN 终结的意思,用来释放一个连接。当
FIN=1
时,表明此报文段的发送方的数据已经发送完毕,并要求释放连接。 - seq 占4个字节(32位),范围[0,\( 2^{32} - 1 \)],一共\( 2^{32} \)个序号,满了之后又会回到 0,也就是\(mod 2^{32}\)。TCP 是面向字节流的。在一个 TCP 连接中传送的字节流中的每个字节都会按照顺序编号。整个要传送的字节流的起始序号要在建立连接的时候初始化。首部中的
seq
指本报文段所发送数据的第一个字节的序号。例如,一段报文的首部seq=301
,而本段报文长度是 100 个字节,所以最后一个字节的序号是 400。下一段报文(如果还有)就应该是seq=401
。这个字段的名字也叫做报文段序号。 - RST 复位(Reset),用来强制关闭连接,套接字直接发送
RST
,从而没有FIN
的发送,接收方收到ECONRESET
错误,连接直接关闭。TCP 链接正常的关闭方式是四次握手,但并不是唯一关闭链接的方式,如果服务器由于某种原因(如连接超时、端口或主机不可达)需要尽快关闭链接就有可能发送RST
包(视服务器操作系统的实现决定)。发送RST
包关闭连接时,不必等缓冲区的包都发出去,直接丢弃缓存区的包然后发送RST
包。而接收端收到RST
包后,也不必发送ACK
包来确认。- 使用
shutdown
、close
关闭套接字,发送的是FIN
,不是RST
close
只有在引用计数为 0 时,才会真正调用close()
,否则只是引用计数减 1,调用close()
,系统会尝试发送完内核缓冲区内所有数据,然后才会发送FIN
shutdown
不理会引用计数和内核缓冲区内的剩余待发数据包,直接发送FIN
。另外shutdown
可以只关闭套接字某个方向的连接,例如关闭发送,关闭接收,或两者都关闭。
- 套接字关闭前,使用
sleep
。对运行的程序Ctrl+C
,会发送FIN
,不是RST
- 套接字关闭前,执行
return
、exit(0)
、exit(1)
,会发送FIN
、不是RST
。 - 想手动发送
RST
包,需要自己伪造数据包进行发送。
- 使用
- PSH
- URG
TCP 建立连接的三次对话过程:
TCP 建立连接之所以需要 3 次,是因为 TCP 是全双工的数据通信,任意一端的连接都可以主动的向对端发送数据,3 次对话确保 A B 两端都能够确认这两条链路都是通的。
- 主机 A 通过向主机 B 发送一个含有同步序列号
SYN
的标志位的数据段给主机 B,向主机 B 请求建立连接,通过这个数据段,A 告诉 B 两件事:1.我想要和你通信。2.你可以用序列号 x 作为起始数据段来回应我。当 B 收到 A 的消息时,B 就可以确认A->B
的链路是通的,但此时 B 并不确定B->A
的链路是否可用。 - 主机 B 收到主机 A 的请求后,用一个带有确认应答
ACK
和同步序列号SYN
标志位的数据段响应 A,也告诉 A 两件事:1.我已经收到你的请求了,你可以传输数据了。2.你要用序列号 y 作为起始数据段来回应我。当 A 收到 B 的应答时,A 就可以确认A->B
、B->A
的通路都是没有问题的(自己建立连接的请求 B 收到了,还发回了响应) - 主机 A 收到这个数据段后,再发送一个确认应答,确认已收到主机 B 的数据段:我已收到回复,我现在要开始传输实际数据了,你准备接收。当 B 收到 A 的确认应答时,B 就可以确认
B->A
的链路是通的。
这样 3 次会话就完成后,主机 A 和主机 B 就可以传输数据了。
TCP 三次会话的特点:
- 没有应用层的数据
SYN
这个标志位只有在 TCP 建产连接时才会被置1
- 握手完成后
SYN
标志位被置0
TCP 建立连接要进行 3 次会话,而断开连接要进行 4 次:
- 当主机 A 完成数据传输后,将控制位
FIN=1
,提出停止 TCP 连接的请求,然后进入FIN-WAIT-1
状态。 - 主机 B 收到
FIN
后对其作出响应,将ACK=1
,确认这一端口上的 TCP 连接即将关闭。主机A收到这个响应后会进入FIN-WAIT-2
状态,等待主机 B 释放连接。 - 主机 B 释放完连接之后,将
FIN=1
,并且ack=u+1
,再提出反方向的关闭请求。 - 处于
FIN-WAIT-2
状态的 A 收到 B 的关闭请求后,将ACK=1
,对 B 的请求进行响应确认,主机 A 进入TIME-WAIT
状态(2ms),然后双方向的连接关闭结束。
主机 A 最后为什么要等待 2MSL 时间呢?因为如果 A 收到 B 发来的释放连接的请求后,响应确认中途丢失了,B 迟迟接收不到响应后会超时(一定小于TIME_WAIT
)重发,A 在等待的时间里面收到请求后可以重新发送响应(A 收到FIN = 1
的请求后WAIT_TIME
会重新记时)。
UDP 是面向非连接的协议,它不与对方建立连接,而是直接就把数据包发过去了。所以 TCP 能够保证数据包在传输过程中不被丢失,但美好的事物必然是要付出代价的,相比 UDP,TCP 实现过程复杂,消耗连接资源多,传输速度慢。
TCP 数据包和 UDP 一样,都是由首部和数据两部分组成,唯一不同的是,TCP 数据包没有长度限制,理论上可以无限长,但是为了保证网络的效率,通常 TCP 数据包的长度不会超过 IP 数据包的长度,以确保单个TCP 数据包不必再分割。
总结一下,传输层的主要工作是定义端口,标识应用程序身份,TCP协议还可以通过保证数据传输的可靠性。
小结 TCP 与 UDP 的区别:
- 基于连接与无连接
- 对系统资源的要求(TCP 较多,UDP 少)
- UDP 程序结构较简单
- 流模式与数据报模式
- TCP 保证数据正确性,UDP 可能丢包,TCP 保证数据顺序,UDP 不保证
应用层
理论上讲,有了以上三层协议的支持,数据已经可以从一个主机上的应用程序传输到另一台主机的应用程序了,但此时传过来的数据是字节流,不能很好的被程序识别,操作性差,因此,应用层定义了各种各样的协议来规范数据格式,常见的有http
,ftp
,smtp
等,http
是一种比较常用的应用层协议,主要用于 B/S 架构之间的数据通信。详细的 HTTP 协议可以参考另一篇文章HTTP 协议
在请求 Header 中,分别定义了请求数据格式Accept
和响应数据格式Content-Type
,有了这个规范以后,当对方接收到请求以后就知道该用什么格式来解析,然后对请求进行处理,最后按照请求方要求的格式将数据返回,请求端接收到响应后,就按照规定的格式进行解读。
所以应用层的主要工作就是定义数据格式并按照对应的格式解读数据。
总结
把以上职责用通俗易懂的话讲就是:当你输入一个网址并按下回车键的时候,首先,应用层协议对该请求包做了格式定义;紧接着传输层协议加上了双方的端口号,确认了双方通信的应用程序;然后网络协议加上了双方的IP地址,确认了双方的网络位置;最后链路层协议加上了双方的MAC地址,确认了双方的物理位置,同时将数据进行分组,形成数据帧,采用广播方式,通过传输介质发送给对方主机,而对于不同网段,该数据包首先会转发给网关路由器,经过多次转发后,最终被发送到目标主机。目标机接收到数据包后,采用对应的协议,对帧数据进行组装,然后再通过一层一层的协议进行解析,最终被应用层的协议解析并交给服务器处理。
OSI 七层模型的意义
物理层
第一层负责最后将信息编码成电流脉冲或其它信号用于网上传输。它由计算机和网络介质之间的实际界面组成,可定义电气信号、符号、线的状态和时钟要求、数据编码和数据传输用的连接器。如最常用的 RS-232 规范、10 BASE-T 的曼彻斯特编码以及 RJ-45 就属于第一层。所有比物理层高的层都通过事先定义好的接口而与它通话。如以太网的附属单元接口(AUI),一个 DB-15 连接器可被用来连接层一和层二。
数据链路层
数据链路层通过物理网络链路提供可靠的数据传输。不同的数据链路层定义了不同的网络和协议特征,其中包括物理编址、网络拓扑结构、错误校验、帧序列以及流控。
- 物理编址(相对应的是网络编址)定义了设备在数据链路层的编址方式
- 网络拓扑结构定义了设备的物理连接方式,如总线拓扑结构和环拓扑结构
- 错误校验向发生传输错误的上层协议告警
- 数据帧序列重新整理并传输除序列以外的帧
- 流控可能延缓数据的传输,以使接收设备不会因为在某一时刻接收到超过其处理能力的信息流而崩溃。
数据链路层实际上由两个独立的部分组成,媒体访问控制(Media Access Control, MAC)和逻辑链路控制层(Logical Link Control, LLC)。MAC 描述在共享介质环境中如何进行帧的调度、发生和接收数据。MAC 确保信息跨链路的可靠传输,对数据传输进行同步,识别错误和控制数据的流向。一般地讲,MAC 只在共享介质环境中才是重要的,只有在共享介质环境中多个节点才能连接到同一传输介质上。IEEE MAC 规则定义了地址,以标识数据链路层中的多个设备。逻辑链路控制子层管理单一网络链路上的设备间的通信,IEEE 802.2 标准定义了 LLC。LLC 支持无连接服务和面向连接的服务。在数据链路层的信息帧中定义了许多域。这些域使得多种高层协议可以共享一个物理数据链路。
网络层
网络层负责在源和终点之间建立连接。它一般包括网络寻径,还可能包括流量控制、错误检查等。相同 MAC 标准的不同网段之间的数据传输一般只涉及到数据链路层,而不同的MAC标准之间的数据传输都涉及到网络层。例如 IP 路由器工作在网络层,因而可以实现多种网络间的互联。
传输层
传输层向高层提供可靠的端到端的网络数据流服务。传输层的功能一般包括流控、多路传输、虚电路管理及差错校验和恢复。流控管理设备之间的数据传输,确保传输设备不发送比接收设备处理能力大的数据;多路传输使得多个应用程序的数据可以传输到一个物理链路上;虚电路由传输层建立、维护和终止;差错校验包括为检测传输错误而建立的各种不同结构;而差错恢复包括所采取的行动(如请求数据重发),以便解决发生的任何错误。传输控制协议(TCP)是提供可靠数据传输的 TCP/IP 协议族中的传输层协议。
会话层
会话层建立、管理和终止表示层与实体之间的通信会话。通信会话包括发生在不同网络应用层之间的服务请求和服务应答,这些请求与应答通过会话层的协议实现。它还包括创建检查点,使通信发生中断的时候可以返回到以前的一个状态。
表示层
表示层提供多种功能用于应用层数据编码和转化,以确保以一个系统应用层发送的信息可以被另一个系统应用层识别。表示层的编码和转化模式包括公用数据表示格式、性能转化表示格式、公用数据压缩模式和公用数据加密模式。
公用数据表示格式就是标准的图像、声音和视频格式。通过使用这些标准格式,不同类型的计算机系统可以相互交换数据;转化模式通过使用不同的文本和数据表示,在系统间交换信息,例如 ASCII(American Standard Code for Information Interchange,美国标准信息交换码);标准数据压缩模式确保原始设备上被压缩的数据可以在目标设备上正确的解压;加密模式确保原始设备上加密的数据可以在目标设备上正确地解密。
表示层协议一般不与特殊的协议栈关联,如 QuickTime 是 Applet 计算机的视频和音频的标准,MPEG 是 ISO 的视频压缩与编码标准。常见的图形图像格式 PCX、GIF、JPEG 是不同的静态图像压缩和编码标准。
应用层
应用层是最接近终端用户的 OSI 层,这就意味着 OSI 应用层与用户之间是通过应用软件直接相互作用的。注意,应用层并非由计算机上运行的实际应用软件组成,而是由向应用程序提供访问网络资源的 API(Application Program Interface,应用程序接口)组成,这类应用软件程序超出了 OSI 模型的范畴。应用层的功能一般包括标识通信伙伴、定义资源的可用性和同步通信。因为可能丢失通信伙伴,应用层必须为传输数据的应用子程序定义通信伙伴的标识和可用性。定义资源可用性时,应用层为了请求通信而必须判定是否有足够的网络资源。在同步通信中,所有应用程序之间的通信都需要应用层的协同操作。
OSI 的应用层协议包括文件的传输、访问及管理协议(FTAM) ,以及文件虚拟终端协议(VIP)和公用管理系统信息(CMIP)等。
常见网络设备
- 集线器(Hub): 从一个设备端口接收信号,原封不动的分发给所有其他的设备端口,由其他端口上的设备决定是否接收,类似广播。工作在物理层(L1)。
- 网桥(Bridge): Bridge 是一个虚拟网络设备,是 Linux 上用来做 TCP/IP 二层协议交换的,与现实世界中的二层交换机功能相似,具有网络设备的特征,可以配置 IP、MAC 地址等。Bridge 设备实例可以和 Linux 上其他网络设备实例连接,类似于在现实世界中的交换机和一个用户终端设备之间连接一根网线,当有数据到达时,Bridge 会根据报文中的 MAC 信息进行广播、单播(转发)、丢弃处理。工作在数据链路层(L2)。
- 交换机(Switch): 一个 N 口的交换机,可以建立
N * (N - 1)
条通信链路,即 \(A_{N}^{2}\)。交换机会判断数据包的类别(广播/单点),查找内部 MAC 端口映射表,定位目标端口号,将数据转发到目标端口或丢弃,自动更新内部 MAC 端口映射表以自我学习。最开始的交换机是二层交换机,工作在数据链路层(L2),但后来根据市场需要,有了三层、四层、七层交换机,分别用于处理不同层的协议。 - 路由器(Router): 根据 IP 地址做数据包的转发。工作在网络层(L3)。
四层/七层负载均衡
所谓几层负载均衡是对应转发方式划分的,四层对应L4传输层,使用IP+端口的方式进行转发,七层对应L7应用层,一般是基于请求URL地址进行代理转发。
从技术原理上
- 四层负载均衡具体实现方式为:通过报文中的IP地址和端口,再加上负载均衡设备所采用的负载均衡算法,最终确定选择后端哪台下游服务器。以TCP为例,客户端向负载均衡发送SYN请求建立第一次连接,通过配置的负载均衡算法选择一台后端服务器,并且将报文中的IP地址信息修改为后台服务器的IP地址信息,因此TCP三次握手连接是与后端服务器直接建立起来的。
- 七层服务均衡在应用层选择服务器,只能先与负载均衡设备进行TCP连接,然后负载均衡设备再与后端服务器建立另外一条TCP连接通道。因此,七层设备在网络性能损耗会更多一些。
从安全角度上
四层负载均衡与服务器直接建立起TCP连接,很容易遭受SYN Flood攻击。SYN Flood是一种广为人知的DDoS(分布式拒绝服务攻击)的方式之一,这是一种利用TCP协议缺陷,发送大量伪造的TCP连接请求,从而使得被攻击方资源耗尽的攻击方式。从技术实现原理上可以看出,四层负载均衡很容易将垃圾流量转发至后台服务器,而七层设备则可以过滤这些恶意并清洗这些流量,但要求设备本身具备很强的抗DDOS流量的能力。
常见四层和七层负载均衡设备
- 四层: F5、LVS…
- 七层: Nginx、Apache…
网络常用命令
# OSX 查看本机所有网络设备信息,包括物理的(网卡),虚拟的(网桥)等等。
$ ifconfig
......
en0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
options=400<CHANNEL_IO>
ether 3c:22:fb:0c:6f:52
inet6 fe80::103f:2585:4804:e5c9%en0 prefixlen 64 secured scopeid 0x6
inet 192.168.8.174 netmask 0xffffff00 broadcast 192.168.8.255
nd6 options=201<PERFORMNUD,DAD>
media: autoselect
status: active
......
bridge0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
options=63<RXCSUM,TXCSUM,TSO4,TSO6>
ether 82:75:90:84:04:01
Configuration:
id 0:0:0:0:0:0 priority 0 hellotime 0 fwddelay 0
maxage 0 holdcnt 0 proto stp maxaddr 100 timeout 1200
root id 0:0:0:0:0:0 priority 0 ifcost 0 port 0
ipfilter disabled flags 0x0
member: en1 flags=3<LEARNING,DISCOVER>
ifmaxaddr 0 port 9 priority 0 path cost 0
member: en2 flags=3<LEARNING,DISCOVER>
ifmaxaddr 0 port 10 priority 0 path cost 0
member: en3 flags=3<LEARNING,DISCOVER>
ifmaxaddr 0 port 11 priority 0 path cost 0
member: en4 flags=3<LEARNING,DISCOVER>
ifmaxaddr 0 port 12 priority 0 path cost 0
nd6 options=201<PERFORMNUD,DAD>
media: <unknown type>
status: inactive
......
# 抓取指定网络设备的数据包
$ sudo tcpdump -n -i en0
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on en0, link-type EN10MB (Ethernet), capture size 262144 bytes
01:52:40.322300 IP 192.168.8.182.49155 > 255.255.255.255.6667: UDP, length 172
01:52:41.043087 IP 17.137.166.35.443 > 192.168.8.174.55832: Flags [P.], seq 1370391690:1370391721, ack 4290356911, win 66, options [nop,nop,TS val 1599036143 ecr 98461104], length 31
01:52:41.043100 IP 17.137.166.35.443 > 192.168.8.174.55832: Flags [F.], seq 31, ack 1, win 66, options [nop,nop,TS val 1599036143 ecr 98461104], length 0
01:52:41.043228 IP 192.168.8.174.55832 > 17.137.166.35.443: Flags [.], ack 31, win 2047, options [nop,nop,TS val 98491147 ecr 1599036143], length 0
01:52:41.043229 IP 192.168.8.174.55832 > 17.137.166.35.443: Flags [.], ack 32, win 2047, options [nop,nop,TS val 98491147 ecr 1599036143], length 0
01:52:41.043856 IP 192.168.8.174.55832 > 17.137.166.35.443: Flags [P.], seq 1:32, ack 32, win 2048, options [nop,nop,TS val 98491147 ecr 1599036143], length 31
01:52:41.044556 IP 192.168.8.174.55832 > 17.137.166.35.443: Flags [F.], seq 32, ack 32, win 2048, options [nop,nop,TS val 98491148 ecr 1599036143], length 0
......