网络是20世纪最伟大的发明之一,众多的设备可以以有线或者无线的方式连入整个互联网,进而互相通信。为了更好的开发、管理、接入网络,科学家设计了通信协议,将整个网络架构分为7层(4层),并规范了每一层的功能。
网络分层
早期的OSI参考模型将网络分为7层:应用层、表示层、会话层、传输层、网络、数据链路层、物理层。为什么要这么分?各层的功能如下:
1.应用层:实现应用间的通信;
2.表示层:提供字符代码、数据格式、控制信息格式、加密等的统一表示。
3.会话层:对传输的报文提供同步管理服务
4.传输层:数据传送的通道;
5.网络层:数据的存储转发;
6.数据链路层:物理寻址,
7.物理层:通过物理媒介上的传输。
OSI参考模型相对繁杂,TCP/IP模型在其基础上进行了相应的简化,将应用、表示、会话这3层压缩成了应用层,将数据链路层、物理层统称为网络通信层。两种分层模式具体如下:
由上图可以看出:OSI参考模型注重通信协议的必要的功能是什么;TCP/IP则更强调在计算机上实现协议应该开发哪种协议、程序。程序员在进行网络编程的时候也上在应用层和传输层上进行操作。
网络通信层
网络接口层和硬件层统称为网络通信层,它定义了数据在在以太网(局域网)中应该遵循什么协议,比如wifi需要遵循IEEE。802.11b或802.11g协议。体现在硬件上就是交换机、网卡等,交换机支持以太网协议,并根据mac地址进行分组转发。mac地址一般被烧入到了ROM中,所以基本上唯一,地址长6个字节,48个比特。
网络层
这一层主要协议有:IP、ICMP、ARP等,实现基于IP地址的数据分包转发。其中还提供了ICMP、ARP等一些辅助协议,ICMP用来发送异常信息,ARP则是从分包数据的IP地址中解析出一种物理地址的协议。IP大致分为3个模块:IP寻址、路由、分包与组包。
目前我们常说的IP地址,一般都是IPv4地址,由4个字节组成。 所以你会经常看到这样的IPv4地址:172.20.6.50,共分为段,用3个英文圆点区分,每段一个字节,这样表示的数字有:2的32次方,大约是42亿。假设每个人都分配一个IP,那么IPv4是不满足所有人的需求的。因此出现了IPv6地址,由16个字节组成,共分为8段,用英文圆点区分,两个字节一段。2的128次方是足以满足所有人对IP地址的需求的。
网络层中的数据格式为“帧”,具体格式分Ip的版本IPv4首部格式如下:
IPv6首部格式如下:
传输层
主要协议为TCP、UDP,其中TCP是一种面向有连接的传输层协议,保证数据的可达性;其中UDP是一种面向无连接的传输层协议,不关注对端是否真的收到了传过去的数据。
TCP的连接过程如下:通过TCP3次握手建立连接,然后开始通信,通信过程中采用一些通信策略优化传输速度和质量,如:窗口控制(多组数据一起发)、拥塞控制等,当需要断开连接的时候,通过TCP4次挥手结束通信。
TCP的3次握手如下图所示(seq表示序列号,ack表示应答号):
为什么需要3次握手呢?假设只有两次握手,A向B发起连接请求,B回应请求,此时A、B之间建立了全双工通信通道(A和B可以互相主动发送消息)。存在如下两种情况:1、如果B的回应正确到达A,那么A已经知道它们之间是建立了通信连接的,然而B不确定:到底是否有建立连接。所以此时B可能再次发起回应,尝试建立连接。造成数据错乱;2、B的回应没有正确到达A,此时B尝试向A发送数据,会造成数据的不可达性。因此A向B发起请求,B回应请求,A再确认请求,共3次握手能够确保的正确性。
TCP的4次挥手如下图所示:
为什么需要4次挥手呢?假设只有3次握手,A向B发起断开连接的请求,B回应请求,A再确认。由于通信通道是全双共的,B再回应断开请求的时候,可能有数据在半路上,还没有到达对端,那么此时到底要不要等呢?所以B作为响应断开连接的一方,是需要做出“决断”的:发送一个FIN信号,表示我不会再发送信息给你,你也不要发送信息给我了。
TCP首部:
UDP首部
注:socket是传输层协议的具体承载体,一般socket编程,就是直接在传输层进行通信。为了发送请求,一般是需要解析TCP/UDP的输入/输出流的,这一点比较麻烦,具体可参考okhttp的解析socket流的过程。
应用层
将OSI参考模型中的应用层、表示层、会话层集中到了应用程序中实现,在日常的开发工作中碰到最多的就是http/https协议。
http协议:
主要有3个版本1.0,1.1,2.0:
1.0是短连接,完成一次请求后,就会断开TCP连接;
1.1是长连接,缓存处理;
2.0是在1.x的基础上引进了:多路复用、二进制分帧、首部压缩、支持服务器推送;
连接过程如下:域名解析 -> TCP三次握手 ->发起http请求 ->服务器响应请求,并返回数据 ->得到反馈数据->完成。本质上是一个单工通信,除非客户端请求,否则服务端不能主动给客户端发送数据。因此推送、IM等需要长连接的模块,一般会选择socket通信(全双工通信)。
http请求行格式如下:
POST .../index.js HTTP/1.1 //请求行
Connection:keep-alive //请求头
...
Accept:xxx //请求头
xxxx //请求体
http响应行格式:
Http1.1 200 Ok //响应行
...
Content-Length:134 //响应头
xxxx //响应体
对比TCP/UDP的数据格式可以看出,其实Http协议对TCP/UDP数据进行更小粒度的细化。也就是说应用层数据对传输层数据进行了一次“格式化”的解析。
https协议
在http的基础上引入了TLS/SSL协议,在传输数据前需要进行一次握手。连接过程:需要7次通信
1. 将自己支持的加密算法发送给服务器;
2. 服务器根据算法选定合适的算法;
3. 服务器发送证书给客户端;
4. 客户端验证证书的合法性;
5. 并利用证书中的公钥将对称加密进行加密后,传给服务器;
6. 服务器利用私钥解密出对称秘钥,并加密数据;
7. 客户端解密数据,开始通信;
总结
希望你了解:1)为什么要有网络分层?各层的功能?2)TCP的连接过程?为什么要3次握手,4次挥手?2)HTTP/HTTPs的连接过程?
欢迎关注微信公众号:“小工说”
扫码关注: