网络模型不是一开始就有的,在网络刚发展时,网络协议是由各互联网公司本身定义的,各家的协议也是不能互通的。这样大大的阻碍了互联网的发展,为了解决这个问题,国际标准化组织 1984 提出的模型标准,简称 OSI(Open Systems Interconnection Model)。具体以下图:javascript
OSI七层模型每一层都有本身的做用,从上到下的做用依次为:html
七层中应用层、表示层和会话层由软件控制,传输层、网络层和数据链路层由操做系统控制,物理层有物理设备控制。java
TCP/IP 模型是由 OSI 模型演化而来,TCP/IP 模型将 OSI 模型由七层简化为五层(一开始为四层),应用层、表示层、会话层统一为应用层。node
TCP/IP协议被称为传输控制协议/互联网协议,又称网络通信协议(Transmission Control Protocol)。是由网络层的IP协议和传输层的TCP协议组成,是一个很大的协议集合。浏览器
物理层和数据链路层没有定义任何特定协议,支持全部的标准和专用的协议。bash
网络层定义了网络互联也就是IP协议,主要包括IP、ARP、RARP、ICMP、IGMP。服务器
传输层定义了TCP和UDP(User Datagram Protocol),咱们会后面重点介绍一下TCP协议。网络
应用层定义了HTTP(超文本传输协议)、FTP(文件传输协议)、DNS(域名系统)等协议。并发
计算机在传递数据的时候传递的都是0和1的数字,而物理层关心的是用什么信号来表示0和1,是否能够双向通讯,最初的链接如何创建以及完成链接如何终止,总之,物理层是为数据传输提供可靠的环境。curl
数据链路层们于物理层和网络层之间,用来向网络层提供数据,就是把源计算机网络层传过来的信息传递给目标主机。 数据链路层主要的做用包括:
网络层位于传输层和数据链路层之间,用于把数据从源主机通过若干个中间节点传送到目标主机,并向传输层提供最基础的数据传输服务,它要提供路由和选址的工做。
那什么是路由和选址呢?
选址
交换机是靠MAC来寻址的,而由于MAC地址是无层次的,因此要靠IP地址来确认计算机的位置,这就是选址。
路由
在可以选择的多条道路之间选择一条最短的路径就是路由的工做。
路由和选址都离不开IP,咱们就详细介绍一下IP头部。
IP头部是由20个字节组成的,具体项所占的位数以下图:
具体的数据咱们用Wireshark来表抓取一下,如图(蓝色部分为IP数据包):
version - 版本
Header Length - 首部长部
Differentiated Services Field - 优先级与服务类型
Total Length - 总长度,该字段用以指示整个IP数据包的长度,最长为65535字节,包括头和数据。
Identification - 标识符,惟一标识主机发送的每一份数据报。
Flags - 标志。分为3个字段,依次为保留位、不分片位和更多片位
Fragment offset - 段偏移量。该分片相对于原始数据报开始处位置的偏移量。
TTL(Time to Live生存时间) - 该字段用于表示IP数据包的生命周期,能够防止一个数据包在网络中无限循环地发下去。TTL的意思是一个数据包在被丢弃以前在网络中的最大周转时间。该数据包通过的每个路由器都会检查该字段中的值,当TTL的值为0时此数据包会被丢弃。TTL对应于一个数据包经过路由器的数目,一个数据包每通过一个路由器,TTL将减去1。
Protocol - 协议号。用以指示IP数据包中封装的是哪一个协议。
Header checksum - 首部校验和。检验和是16位的错误检测字段。目的主机和网络中的每一个网关都要从新计算报头的校验和,若是同样表示没有改动过。
Source - 源IP地址。该字段用于表示数据包的源地址,指的是发送该数据包的设备的网络地址。
Destination - 目标IP地址。该字段用于表示数据包的目标的地址,指的是接收节点的网络地址。
传输层是面向链接的、可靠的的进程到进程通讯的协议。TCP提供全双工服务,即数据可在同一时间双向传播。TCP将若干个字节构成一个分组,此分组称为报文段(Segment)。提供了一种端到端的链接。
传输层的协议主要有TCP 和 UDP,TCP(Transimision Control Protocal)是一种可靠的、面向链接的协议,传输效率低。UDP(User Datagram Protocal)是一种不可靠的、无链接的服务,传输效率高。 下面重点介绍一下TCP的三次握手和四次挥手。
TCP主要是将数据进行分段打包传输,对每一个数据包编号控制顺序,运输中丢失、重发和丢弃处理。
有点和IP头相似,咱们先来张图看下:
Source Port & Destination Port - 源端口号和目标端口号;计算机经过端口号识别访问哪一个服务,好比http服务或ftp服务;发送方端口号是进行随机端口;目标端口号决定了接收方哪一个程序来接收。
Sequence number - 32位序列号,TCP用序列号对数据包进行标记,以便在到达目的地后从新重装。在创建链接时一般由计算机生成一个随机数做为序列号的初始值。
Acknowledgment number - 32位确认号,确认应答号。发送端接收到这个确认应答后,能够认为这个位置之前全部的数据都已被正常接收。
Header Length - 首部长度。单位是 '4'个'字节',若是没有可选字段,那么这里的值就是 5。表示 TCP 首部的长度为 20 字节。
checksum - 16位校验和。用来作差错控制,TCP校验和的计算包括TCP首部、数据和其它填充字节。
flags - 控制位。TCP的链接、传输和断开都受这六个控制位的指挥
window size - 本地可接收数据的数目,这个值的大小是可变的。当网络通畅时将这个窗口值变大加快传输速度,当网络不稳定时减小这个值能够保证网络数据的可靠传输。它是来在TCP传输中进行流量控制的
三次握手和四次挥手究竟是怎么回事呢,我用一台主机A(172.16.50.72:65076)起一个服务,另一台主机B(172.16.17.94:8080)请求一下。 在A主机上启动node服务:
let http = require('http');
let url = require('url');
let server = http.createServer();
server.on('request', (req, res) => {
let {pathname, querry} = url.parse(req.url, true);
let result = [];
req.on('data', (data) => {
result.push(data);
})
req.on('end', () => {
console.log(Buffer.concat(result).toString());
res.end('hello world');
})
})
server.listen(8080, () => {
console.log('server started');
});
复制代码
B主机链接A并发送数据:
curl -d "user":"lucy" 172.16.17.94:8080
复制代码
用wireshark抓包演示一下。以下图:
上图中A为三次握手,B为数据传输,C为四次挥手。下面咱们详细介绍一下这三个部分。
首先咱们先图解一下wireshark抓到的数据,以下图:
咱们把这个过程分为三部分,第一部分为三次握手创建链接,第二部分为数据传输,第三次为四次挥手断开链接。
三次握手
咱们分析一下三次握手的过程(包括ack 和 seq的值变化),
第一次握手: 创建链接。客户端发送链接请求,发送SYN报文,将seq设置为0。而后,客户端进入SYN_SEND状态,等待服务器的确认。
第二次握手: 服务器收到客户端的SYN报文段。须要对这个SYN报文段进行确认,发送ACK报文,将ack设置为1。同时,本身还要发送SYN请求信息,将seq为0。服务器端将上述全部信息一并发送给客户端,此时服务器进入SYN_RECV状态。
第三次握手: 客户端收到服务器的ACK和SYN报文后,进行确认,而后将ack设置为1,seq设置为1,向服务器发送ACK报文段,这个报文段发送完毕之后,客户端和服务器端都进入ESTABLISHED状态,完成TCP三次握手。
数据传输
四次挥手
当客户端和服务器经过三次握手创建了TCP链接之后,当数据传送完毕,就要断开TCP链接了,就有了神秘的“四次挥手”。
第一次挥手:客户端向服务器发送一个FIN报文段,将设置seq为160和ack为112,;此时,客户端进入 FIN_WAIT_1状态,这表示客户端没有数据要发送服务器了,请求关闭链接;
第二次挥手:服务器收到了客户端发送的FIN报文段,向客户端回一个ACK报文段,ack设置为1,seq设置为112;服务器进入了CLOSE_WAIT状态,客户端收到服务器返回的ACK报文后,进入FIN_WAIT_2状态;
第三次挥手:服务器会观察本身是否还有数据没有发送给客户端,若是有,先把数据发送给客户端,再发送FIN报文;若是没有,那么服务器直接发送FIN报文给客户端。请求关闭链接,同时服务器进入LAST_ACK状态;
第四次挥手:客户端收到服务器发送的FIN报文段,向服务器发送ACK报文段,将seq设置为161,将ack设置为113,而后客户端进入TIME_WAIT状态;服务器收到客户端的ACK报文段之后,就关闭链接;此时,客户端等待2MSL后依然没有收到回复,则证实Server端已正常关闭,客户端也能够关闭链接了。
注意:在握手和挥手时确认号应该是对方序列号加1,传输数据时则是对方序列号加上对方携带应用层数据的长度。
应用层常见协议有HTTP、HTTPS 、FTP 、SMTP等。
TCP/IP模型咱们基本介绍完了,那层与层之间是怎样合做和分工的呢,咱们用两张图介绍一下: 发送方的数据是从上往下传输的,即从应用层向物理层传输。接收方的数据是从下往上传输的,即从物理层向应用层传输。以下两张图。
发送方是从高层到低层封装数据:
深刻理解TCP/IP模型就简单介绍完了,若是有理解错误的地方,欢迎指正!