网络分层基础概念:
与ISO的OSI网络分层模型不同。网络分层事实上的标准为TCP/IP 的网络分层模型。
下图是他们是他们之间的对应关系。
左边为OSI网络分层模型。右边为TCP/IP的网络分层模型。
网络分层,是将一个大而复杂的网络,拆分为多个层次,每个层次单独完成自己的任务,多个层次再结合起来,完成一个复杂的通信过程。下层协议,为上层提供服务。这样拆分的好处不仅是将一个复杂的任务分成小任务分别完成,并且拆分之后,不同的层次之间,若是出了问题,可以迅速定位,还有一点就是每一层之间,通过接口进行传输,这使得每一层是独立的,他们的关系非常灵活。比如,数据链路层不用这物理层是通过网线还是无线传输的,只要收到物理层传输过来的电磁信号即可,网络层也不用管数据链路层是通过交换机,还是集线器完成不同的MAC地址之间的通信,只要收到数据链路层传输过来的信号即可。独立分层之后,关系非常灵活。
我们简单来描述一下每一层到底是什么,他们是做什么的。
物理层:定义物理传输介质的特性。这一层最底层,像定义用光纤传输,还是用同轴线缆传输之类的。
数据链路层:
主要是说设备到设备之间的通信。其实就是MAC地址之间的通信了。我们都知道,不同的主机,MAC地址是不同的。MAC地址分为六段,前三段为厂商的固定编号,后三段为不同的主机之间进行唯一标识的编号。当一个网络中主机数量多的时候,就需要用到交换机来将众多的主机相连起来,并且采用载波侦听,多路访问,冲突检测机制保证主机与主机之间进行有效通信。简称CSMA/CD此后,在MAC底层采用此种机制通信的网络,都称为以太网。这就是以太网的由来。
网络层:
数据链路层只完成同一局域网中的不同主机之间的通信,那不在同一局域网中的主机如何进行通信?这就要靠网络层中的Internet protocol协议来进行界定。MAC地址是物理上的地址,可以说是唯一且固定不变的。它在局域网上工作是没问题的,若不在同一网络中,MAC地址如何进行通信?这几乎是不可能的事情,所以我们需要在MAC地址之上,再给主机附加一层逻辑上的地址,进行网络界定,判断他们是否在同一网络内,若不在同一网络内,如何通过路由将报文送到另一网络中,进行通信。为了解决网络层的这个问题,诞生了大名鼎鼎的IP协议。
传输层:
通过数据链路层与网络层,同一网络上主机与主机之间的连接,不同网络间主机与主机之间的连接都已经得到解决,但连接起来之后,要进行怎样的通信?我们知道通信的种类大体可以分为两种,TCP和UDP。TCP主要是面向连接,有错误检测,有确认机制,可重传的连接,像我们平时下载应用程序就是一个非常典型采用TCP协议进行连接的例子,若是采用UDP进行连接,可靠性将得不到保障,大家都知道,对于一个应用程序而言,若是传输过程中少了一个即使一个字节,都可能会使这个应用程序跑不起来。UDP是非面向连接,但速度非常高效的连接,最典型的就是通过QQ发送的短消息,无需要对方在线,只要将信号往网络中一发,完事。即使对方收不到,也可以重发一次,无需非常苛刻的可靠性。
应用层:
其实,说主机与主机之间的通信,是不精确的,在本质上,通信都是进程与进程的通信。不同的进程,监听在不同的端口号上,比如HTTP服务,监听于80端口,MYSQL服务,监听于3306端口,SSH(Secure shell)服务,监听于22端口,FTP服务,监听于21端口。不同的服务之间进行通信,也有不同的协议,著名的有http(超文本传输)协议,FTP(文件传输)协议,DNS(域名解析)协议
通过上边的简单介绍,相信大家对网络分层有了一个基本的概念,并且每层是分别完成网络通信中的什么动作,也有了大体了解。
网络通信的学习,最难的就是传输层与网络层。下面我们重点是解析一下传输层与网络层。
因为通信是进程与进程之间的通信,数据首先是从应用层进行封装,再到传输层,再到网络层的,然后是数据链路层,再到物理层。
先了解报文是什么:报文(message)是网络中交换与传输的数据单元,它包含了完整的传输与交换信息。
并且长度并不是一致的。为什么?因为报文有大小,报文在传输的过程中,传输到不同的网络分层时,会被不断的分解。并且在不同的分层中,它的称呼也是一不一样的。
应用层的一个报文,到传输层时,若是传输层的TCP协议进行传输,因为tcp是面向连接,可靠的,可重传的协议,为了保证可靠性,报文就会被分段进行传输,形成一个一个的数据段(seqment),若是对方没有收到某个段,则再重新发送此数据段。若是用UDP进行传输,则是无论大小,直接以数据报(datagram)的方式进行传输,传完即可,十分高效,也不需要关心对方是否在线,对方是否接收到报文。
无论是以TCP或是UDP方式进行传输,到达网络层时若数据段或数据报太大,将会被分成许多小的数据包进行传输,因为路由器的MTU(Max Transmission Unit)是有限制的。
到了数据链路层,每个数据包加上侦头与侦尾之后,就形成了侦(frame),并以侦的方式进行传输。
到了物理层,再以位(bit)的方式进行传输。
他们的包含关系大体如下。
先说说传输层。传输层,就是讲应用层下来的报文,如何进行传输,是通过TCP,还是UDP。
当通过tcp时,报文都被拆分成数据段(sqement)的方式进行传输。这些数据段内部的结构如下图。
TCP的数据段部分主要包含了应用层报文的应用层首部与应用层数据报文。
我们重要解析一下TCP的首部组成。
先说端口,大家有没有想过,在应用层上,进程与进程之间的通信,是如何分辨众多进程中,发起通信的进程是如何在另一台主机上找到另一个它要通信的进程呢?
靠的就是端口。TCP与UDP都向上层的进程提供了不同的端口号。并且这些端口号是固定的,如HTTP进程,就应该监听在TCP提供的80端口上,虽然这不是强制规定,但却是一种共识。不然就无法进行通信,当然这指的是服务端的HTTP进程。客户端的进程是临时由内核指派的。所以想要进行进程间的通信,就先要指明端口号。
接下来是序号,需要注意的是序号是相对的,两个进程开始通信,相对来讲序号都是从0开始。
再到确认号,这个有些特殊,意为收到了对方的数据,并且值是希望对方下次发的那个数据的序号。比如上次对方发的是x,那确认号应该为ack=x+1。
数据偏移:现在我们知道,在TCP协议的传输中,为了保证可靠性,数据是分组传输的,分组传输之后这些数据如何恢复呢?就是靠偏移量来计算的。
标记位:都是一个字节,值当然不是1就是0了。
标记位主要有:
UGR:紧急数据
ACK:确认号
PSH:是否缓存
RST:连接出现严重错误,需要重传
SYN:同步序号。当SYN=1 ACK=0时意为请求连接,SYN=1,ACK=1时意为同意连接。一般用在TCP前两次握手中。
FIN:请求结束标记
窗口:我们知道,主机与主机之间,根据网卡的性能,网络的速度,接收报文的吞吐量是不同的,这时就要靠“滑动窗口”来调整大小,先发较小单位的数据,慢慢增加,若对方表示已经到达上限,则停止增加,双方达到最佳传输速度。
紧急指针:我们知道,内核处理数据也是需要时间的,当URG为1 时,表示此报文需要立即处理,不能等待,相当于能插队的意思。
要分析TCP就不能不说TCP的三次握手与四次断开。
TCP号称面向连接,是可靠的,有错误检测,可重传的连接,就是靠这些复杂的确认机制来实现的。
那么他们是如何工作的呢?
TCP建立连接的时候,我们称为三次握手。
这要求,对方必须在线,这就是面对连接的由来。
三次握手与主机状态的变化:
先了解这些单词是如何来的:
SYN: sync 同步
ACK:acknowledgement 标记位确认号
seq: sequence 序号
ack: acknowledgement 数据段确认号
解析:
1:当客户端请求连接时,发出一个SYN=1的同步信号,相当于说“我准备好啦,通信吗?”,并且发送序号为x的数据段过去。即seq=x,同时发送一个ack=y,意为请求对方下次发送一个序号为y的包过来。SYN=1 ACK=0 seq=x ack=y
客户主机的状态由CLOSE(关闭)状态进入SYN-SENT(同步——已发送)状态。
2:服务器端收到请求之后,若服务器端同意,也发一个SYN=1的同步信号,相当于说“我也准备好啦,可以通信!”,并且发送一个ACK=1的确认报文,表示客户端上次发送的报文服务器端已经收到,seq=y表示服务器响应给客户端请求,将序号为y的数据段发送出去。并且再发送一个ack=x+1表示客户发过来的x数据段已经收到,请求客户端下次发送序号为x+1的数据段过来。SYN=1 ACK=1 seq=y ack=x+1
由于服务器是被请求方,所以是被动打开,并且进入监听状态,监听来自客户端报文。当服务器发送完同意请求的报文后,就进入了SYN-RCVD(同步—已接收)状态。
(大写的ACK是确认号,小写的ack是数据段的相对序号,并且当SYN=1时,发送的数据段不能携带数据,即发送的是空的数据段,但要占一个序号。)
3:通过前面两次同步,得知双方都在线,第三次就不必再发SYN标记了。客户端收到服务器的响应报文后,发送一个ACK=1的确认信号,并且发送一个ack=y+1表示服务器发送过来的序号为y的数据段已经收到,请求服务器发送序号为Y+1的数据段,同时发送sqe=x+1,即将服务器请求的x+1的数据段发送出去。
ACK=1 ack=y+1 seq=x+1
此时客户端已经得到服务器端同意请求的回应,于是从SYN-SENT(同步发送状态)进入连接状态,并且发送一个ACK=1的报文告诉服务器可以进行连接状态了。服务器端收到ACK=1信号后,也从SYN-RCVD(同步接收状态)进入连接状态。
这时大家可能有一个疑问,第一,第二次握手时,同步状态都已经确认了,为什么还要再来第三次?这里有一种情况需要说明一下。若是网络上出现延迟,假设client端发送的请求很长时间才到达service端,在这段时间内client由于得不到回应而进入close。而这个请求并没有在网络上消失,只是在网络上延迟送达,当service收到请求后,并不知道client已经进入close状态,于是同意发送建立连接响应,并进入syn-rcvd状态。注意,由于client已经释放了上一次的请求并进入close状态,是根本不会收到service的同意建立连接的响应的,自然谈不上去响应service。而此时serivce一直处于listen状态,白白浪费资源。所以才需要第三次握手来再次确认是否真的要建立连接。
通信上述解析,相信大家对于TCP协议的原理也有了一个大概的了解。
有握手就有断开,我们再来聊聊TCP协议的四次断开时,标记位的变化与主机机状态的切换。
四次断开:
1:客户端请求断开,并且从连接状态进入fin-wait-1。此刻发送的数据段标记位的值为:FIN=1 sqe=x
2: 服务器立即确认收到信号,但并不会立即断开,因为可能还有数据没传完呢。所以响应的数据段的标记位值为:ACK=1 sqe=v ack=u+1。并且也从连接状态进入close-wait状态同时继续将未完的数据段继续传输。
而客户端收到确认信号后,也从fin-wait1进入fin-wait状态,等待服务器数据传输完成之后发送断开确认信号。
3:当服务器数据传输完毕后,就会发送断开连接确认,此时的标记位的值为:FIN=1 ACK=1 sqe=w ack=u+1。并且从close-wait状态,进入last-ack状态。
(seq此时为为v+1是因为服务器给客户端发送了许多数据段)
4:客户端收到确认断开连接的信号后,立即跟服务器发确认信号:ACK=1 seq=u+1 ack=w+1表示服务器可以断开连接,并且自己也进入time-wait状态等待一定的时间后自动进入close状态。
呼,费了一大通力气解释TCP,大家有没有一个大概的了解?
下面我们来解析一下UDP协议的工作机制。
UDP的工作特性:
优点:高效
缺点:提供网络通信并不可靠,无错误检查,无数据恢复特性。
UDP首部:源端口,目标端口,数据报长度,校验值。
UDP全称User Datagram Protocol,它所发送的报文,并不分段,是无论大小直接向网络上扔出去的,所以上层的报文进入UDP协议后称为数据报。
并且UDP首部相对简单许多。只有源端口,目标端口,报文长度,检验和。他并不像是TCP有一系列复杂的确认机制,也无需要对方是否在线,直接往网络中发送,所以并不能保证通信的可靠性,不面向连接,自然无从谈错误检测和数据重传了。
讲完传输层的两大重要协议,下面我们再来讲讲网络层的ip协议。
先来思考一个问题:
A网络中的1主机,要与B网络中的2主机进行通信,他们之间要如何进行通信呢?
可能大家会说,可以基于MAC地址进行通信。若1知道2的MAC地址,自然可以通信,但前提得先要他们在同一局域网中,不然既然1知道2的MAC地址,通过交换机在局域网上进行广播,2主机不在1主机的A网络中,是不可能响应这个广播的。
1主机与2主机根本不在同一网络中,他们之间要进行通信,就要先解决A网络与B网络的互联。
一个新的问题又来了。
1主机与2主机又是如何得知他们不是在同一个网络中的呢?
这就需要一个判断机制。
光有MAC地址,只能标记主机是唯一的,并不能标识应该主机所在的网络,我们需要逻辑上的一层地址,来对网络中的已经有唯一标识的主机进行地址界定。这就是IP协议的由来。
有了IP地址之后,1与2就能通过IP判断对方是否与自己在同一网络中了。假设1的IP为192.168.22.168,2的ip为192.168.33.168。通过网段的比较,1就知道2根本不与自己在同一网络中,自然不会发广播,而是直接将报文发给默认网关,让网关帮忙将报文一个网络中的2主机所在的B网络。从而让2主机收到报文。
IP协议是如何对不同的网络进行标识的呢?
这个问题有点复杂,我们得先要了解一些IP地址的分类。
主要有三类:
A:1.0.0.0 — 126.255.255.255
B: 128.0.0.0 –191.255.255.255
C: 192.0.0.0 –223.255.255.255
D和E由于不常见,就不讨论。
0.0.0.0用于主机刚刚开机还没有IP的时候,DHCP就要靠这个申请IP。
255.255.255.255限制广播地址,对本机来说,这个地址是指本网段且同一广播域内的的所有主机。
127.0.0.1–127.255.255.254用于本地回环,主要有测试的功能。
10.0.0.0是A类网的私有地址,172.16.0.0 — 172.32.0.0是B类网的私有地址,192.168.0.0—192.168.255.0是C类网的私有地址。这三种私有地址都能在局域网中进行通信,但是不能在广域网中进行通信。
组播地址,在高可用集群服务中有应用。
子网掩码:主要用于界定网络ID与主机ID。A类网的掩码为255.0.0.0。B类网的掩码为255.255.255.0。C类网的掩码为255.255.255.0。
给定一个IP地址,通过与子网掩码进行与运算,就能得到网络ID。计算机就是靠先将自己的IP地址与子网掩码进行与运算得出网络ID后,再将目标的IP地址与自己的掩码相与,若得出的网络ID一样,则知道这IP是与自己在同一网段上,于是直接在本网段发广播,若得到的网络ID不一样,则发送到默认网关处,让网关路由,将报文传输到目标IP。
先了解当上层的TCP/UDP数据段或是数据报到达这一层后,是如何传输的。
上层的数据,到达这一层后,通常会被分成一个一个的包传送,称为数据包。
而每一个数据包,也是包头与数据部分组成的。如下图。
我们重点分析一下,IP首部到底包含了哪些信息。
版本号:通常有IPV4 和IPV6两种。占4位。
首部长度: 用来标识IP首部长度的。占4位。首部长度一般为20字节,但妆IP有填充时,就不一定了,但最多可有60字节。
总长度:占16位,标识整个数据包的长度的,包括数据部分长度。由此可知整个数据包最大可为2^16减去1。即65535个字节。
标识:由上可知,即数据包最大只能为65536字节,那如果我们要传输一个传输层的UDP协议下来的总共大小为1M的N个数据报,这1M的数据报就要被切割成1M/65535B个数据包。这些来自同一个数据报的数据包就要打上相同的标识,好让对方主机收到之后,能在网络层的拆包时根据标识来识别应该将哪些数据包合成一个数据报,一般情况下,TCP由于MSS大小的限制,都会先将报文分段,而分段的大小都是小于MTU限制的,所以TCP的数据段在网络层一般都不会被分片传输。
片偏移:光打上标识还不够,打上标识仅能表明这些数据包是同一数据报的,对方对到之后,还要靠片偏移来将同一个数据报的数据包进行有序组合,才能对数据报进行还原。
标志:主要标志数据包是否经过分片的。有时传输层下来的数据段,数据报,并不需要再切割分片,就要靠标志位来标志。
寿命:Time to live,数据包也是有生命周期的,linux为64,windows为128。它是以经过的路由器的个数算的,每经过一个路由器值就减1,为0时将不再被路由,直接丢弃。
协议:标明上层用的是什么协议。
好了,以上就是TCP/IP协议栈中最主要的两层的介绍,以及各层协议的分析。希望对大家有用。
原创文章,作者:old_radish,如若转载,请注明出处:http://www.178linux.com/74758