TCP/IP协议是Internet互联网最基本的协议,其在一定程度上参考了七层OSI(Open System Interconnect,即开放式系统互联)模型
OSI参考模型是国际组织ISO在1985年发布的网络互联模型,目的是为了让所有公司使用统一的规范来控制网络,让所有的公司遵循相同的通信规范,使网络能够互联互通;
OSI模型定义了网络互联的七层框架(物理层、数据链路层、网络层、传输层、会话层、表示层、应用层),每一层实现各自的功能协议,并完成与相邻层的接口通信。
在TCP/IP
协议中,OSI
的7层被简化为4层,分别是链路层(也称为数据链路层或网络接口层)、网络层、传输层、应用层;
应用层协议:HTTP
、Telnet
、SMTP
、FTP
、DNS
等;主要是为了接收来自传输层的消息,或将数据传输写入传输层;
传输层协议:TCP
、UDP
等;主要是为了实现端对端的数据传输、传输服务分为可靠(TCP
)与不可靠(UDP
)、为端到端提供流量控制、差错控制、QoS
(Quality of Service);
网络层协议:IP
、ICMP
(Internet Control Message Protocol)、IGMP(Internet Group Management Protocol,网络群组管理协议)等;主要是为了网络中的数据包传送;
链路层协议(又称为数据链路层或网络接口层):ARP
(地址解析协议)、RARP
(逆地址解析协议)等;通常包括操作系统中的设备驱动程序或计算机中对应的网络接口卡,它们一起处理与传输媒介(如电缆或其它物理设备)的物理接口细节;
每一层协议的作用
物理层:使用MAC地址解决设备身份问题;
通信工具的演变史:单根或多跟网线、集线器、交换机、路由器
单根或多跟网线:用一根网线将两台电脑连接起来就可以进行通信,至于它们为什么能够进行通信,这就涉及到操作系统方面的知识,大家有兴趣可以去了解一下IO
、中断、缓冲区、以及网卡是如何转换成电信号等,或者后面我在整理一下这方面的知识。
集线器:随着越来越多的电脑设备加入,每台电脑上需要开的网口会越来越多,但是一台电脑所开的网口有限,不可能无限增加网口,于是就出现了集线器,即中间器。将每一台电脑的网线插入这个集线器,由这个设备进行转发,这样每台设备就可以彼此进行通信。这种集线器的通信模式本质上与单根或多根网线的通信方式是一样的,只是每台电脑的网口数量减少了。
集线器仅仅是电脑将电信号转发到所有出口(广播),对转发消息不做任何处理。如,在A向B发送数据时,只需要在数据包头部提供源MAC地址和目标MAC地址,当B收到数据包后,只需根据数据包头部的目标MAC地址判断是否是发送给自己的,而其它设备在收到数据包后,也是一样通过从数据包头部的目标MAC地址判断是否发送给自己的,如果目标MAC地址与自己的MAC
地址不一致,便丢弃该数据包。
虽然集线器使整个布局变得简洁,但是从A发到B的数据,会将数据包发给所有连接该集线器的设备,容易造成数据的安全性问题,而且也容易浪费网络资源。
那么,假如是否存在一种设备,能够将数据只发送给B设备呢?
交换机:为了解决集线器的问题,将消息只发送给目标MAC
地址所指向的设备,该设备放在数据链路层。
交换机内部维护着一张MAC
地址表,记录着每一台设备的MAC地址,同时也记录着该设备连接在哪一个端口上。假设A设备发送数据到B设备,当数据包到达交换机时,交换机通过查内部维护的MAC地址表,发现B设备的MAC地址为XXXX,在1号端口上,于是交换机将数据包从1号端口发送到B设备,通过这种传输方式而组成的小范围网络,我们称之为以太网。
当然,MAC
地址表刚开始建立时是空的,当你向B设备发送消息时,A设备的消息从端口1发出,此时交换机将A设备的MAC
地址和端口号记录到交换机内部映射表中,当交换机在内部映射表中查不到B设备的MAC
地址和端口号时,会将此数据包发送给所有端口,即发给了所有设备,当只有机器B收到数据是发送给自己时,于是做出响应,响应码从3号端口发出进入交换机,此时交换机会在MAC
地址表中更新B设备的MAC地址和端口。当该网络中的机器不断通信时,交换机中的MAC
地址表会不断完善。
但是,随着网络中的设备数量越来越多,交换机内部需要维护的MAC地址数量也越来越多,交换机的端口数量会出现不足。
此时交换机已经无法满足如此庞大的映射关系。
路由器:作为一台独立的拥有MAC
地址的设备,并且可以把数据包做一次转发(注意:路由器的每个端口都拥有独立的MAC
地址);路由器是属于网络层。路由器专门负责IP
地址的寻找。
有了路由器,自然而然就诞生了IP
地址,IP
地址长度为32位,而MAC
地址长度为48位;
当A设备与C设备不在同一个子网时,A设备会将数据包发送给路由器,然后由路由器进行转发;
但是,A设备是怎么知道和C设备不在同一个子网,以及A如何知道那台设备是路由器?
这时就诞生了子网和网关
子网得由来:
A给C发送数据,怎么知道是否要通过路由器进行转发?答案是通过子网
目的IP和源IP处于同一个子网,直接通过交换机进行转发;
目的IP和源IP不处于同一个子网,就交给路由器去进行处理;
假入某台子网掩码定义为255.255.255.0
将源IP和目的IP分别与这个子网掩码进行与运算,相等则是在一个子网,不相等就是在不同的子网。例如,对于192.168.0.1来说,192.168.0.xxx就算是在一个子网,否则就是在不同子网。
比如:
A电脑:192.168.0.1&255.255.255.0 = 192.168.0.0
B电脑:192.168.0.3&255.255.255.0 = 192.168.0.0
C电脑:192.168.2.1&255.255.255.0 = 192.168.2.0
D电脑:192.168.2.6&255.255.255.0 = 192.168.2.0
那么A与B在同一个子网,C与D在同一个子网,但是A与C和D不在同一个子网;
默认网关(如192.168.0.254),当A与C不在一个子网时,A会将包发送到同一子网下的默认网关,至于是那台设备,A不在关心,只需发出即可。
子网掩码其实就是表示前多少位为子网网段,如192.168.0.0(255.255.255.0),可以简写为192.168.0.0/24;
当A向C传输数据时,除了加上数据链路层的头部之外,还要在增加一个网络层的头部;
A发送给路由器的信息如下:
路由器发送给C的信息如下:
至于上述过程的发送流程为什么是这样,与前面讲到的子网有关系,理解了子网的概念,就明白了A到C的发送过程;
至于路由器怎么知道收到的这个数据包该从自己的那个端口出去呢?
答案是路由器中也维护着一张路由表,与MAC地址表一样。不同于MAC地址的是,路由表并不是一对一的确定关系;
由于子网掩码其实就是表示前多少位表示子网网段,如192.168.0.0(255.255.255.0)也可以简写为192.168.0.0/24;
于是,路由表就表示,192.168.0.XXX的都发送到0好端口,192.168.1.XXX的都发送到1号端口,上图中下一跳暂时没有值,可以先忽略;
这样我们从A发送到C的数据,就能够正常发出;
但是,现在又有一个问题,发送数据还需要数据链路层的包,而我们只知道IP地址,数据是怎么发送出去的呢?
答案是ARP协议,在网络层中,通过IP地址找到对应设备的MAC地址,同时电脑A和C都会缓存一张ARP缓存表,记录着IP与MAC地址的对应关系;
刚开始的时候,ARP缓存表是空的,A为了知道C的MAC地址,将会广播一条ARP请求,C收到该请求后,将会发送自己的MAC地址和响应码,A收到后便更新了自己的ARP缓存表。
通过这种方式不断的进行广播ARP
请求,最终电脑里面的ARP缓存表都将会更新完整;
上面讲到的MAC
地址表、路由表、ARP
缓存表,这三张表是怎么来的呢?
MAC
地址表:以太网内各节点之间不断通过交换机通信,逐步进行完善;用于映射MAC
地址和它的端口号;
路由表:路由算法+人工配置逐步完善;用于映射IP地址和它的端口号;
ARP
缓存表:通过ARP
协议广播请求逐步完善;电脑和路由器中都有ARP缓存表,用于IP
地址和MAC
地址的映射关系;
HTTP
报文传输原理
利用TCP/IP
进行网络通信时,数据包会按照分层顺序与对方进行通信。发送端从应用层往下走,接收端从链路层往上走。从客户端到服务端的数据,每一帧的数据传输顺序为:应用层–>传输层–>网络层–>链路层–>链路层–>网络层–>传输层–>应用层;
TCP
协议的报文格式
在TCP/IP
协议栈中,IP
协议层只关心如何使数据传输跨越本地网络的边界问题,而不关心数据是如何传输。整体的TCP/IP
协议栈,共同配合解决数据如何通过许多个点对点通路,顺利传输到达目的地。一个点对点通路被称为一跳(hop),通过TCP/IP
协议栈,网络成员能够在许多“跳”的基础上建立相互的数据通路。
传输层TCP协议提供一种面向连接的,可靠的字节流服务,其数据帧格式如下图所示:
TCP协议的数据帧,大致分为以下几个部分:
源端口:源端口表示报文的发送端口,占16位。源端口和IP地址组合起来,可以标识报文的发送地址;
目的端口:目的端口表示报文的接收端口,占16位。目的端口和IP地址组合起来,可以标识报文的接收地址;
序号:TCP
传输过程中,发送端发出的字节流中,传输报文的数据部分的每一个字节都有它的编号。序号占用32位,即4个字节,发送方发送数据时,都需要标记序号。
序号与SYN
控制标志的值相关,根据控制标志中的SYN
是否为1,序号表达的含义不同:
(1)当SYN
=1时,当前为连接建立阶段,此时的序号为初始序号ISN
,通过算法来随机生成序号;
(2)当SYN
=0时,在数据传输开始时,第一个报文的序号为ISN+1
,后面的报文序号为前一个报文的SN
值+TCP
报文的净字节数(不包含TCP头)。例如,如果发送端发送的一个TCP
帧的净荷为16byte,序号为6,则发送端在发送下一个数据包时,序号应设置为:16 + 6 = 22;
在数据传输过程中,TCP
协议通过序号对上层提供有序的数据流。发送端可以根据序号来跟踪发送的数据量,接收端可以根据序号来识别重复的TCP
包,从而将重复的TCP
包丢弃,对于乱序的数据包,接收端可以根据序号进行排序。
确认序号:标识报文接收端期望接收的字节序列。如果设置了ACK
控制位,确认序号的值表示一个准备接收的包的序列码,它所指向的是准备接收的数据包,也就是下一个期望接收的包的序列码;
假设发送端发送6个净荷为1024byte
,起始SN号为1的数据包给服务端,服务端每收到一个包之后,需要回复一个ACK
响应,确认数据包给发送端,ACK响应数据包的ACK值为每个发送端包的SN
+包净荷,表示服务端已经接收到的字节数,还表示期望收到下一个发送端发送数据包的SN序号。
只有控制标志的ACK
标志为1时,数据帧中的确认序号ACK
序号才有效。TCP
协议规定,在建立连接后,所有发送报文的ACK
值必须为1,所有报文的确认序号有效。如果是SYN类型的报文,ACK
标志为0,没有确认序号。
头部长度:该字段占用4位,用来表示TCP
报文的首部长度;其值所表示的并不是字节数,而是头部的所含有的32bit的数目(或者倍数),或者4个字节的倍数,所以TCP头部最多可以有60字节(4*15=60)。没有任何选项字段的TCP
头部长度为20字节,所以其头部长度为5,可以通过20/4=5计算得到。
预留6为:头部长度后面预留的字段长度为6位,作为保留字段,暂时没有什么用处。
控制标志:控制标志(Control Bits)共6个bit位,具体的标志位为:URG、ACK、PSH、RST、SYN、FIN
。
窗口:长度为16为,共2个字节。此字段用来进行流量控制,流量控制的单位为字节数,表示接收方一次希望收到的字节数;
校验和:长度为16位,共2个字节。对整个TCP
报文段和数据进行校验和计算,接收端用于对收到的数据包进行验证;
紧急指针:长度为16为,共2个字节。它是一个偏移量,与SN
序号值相加表示紧急数据最后一个字节的序号;
以上是TCP
协议报文首部必须需要的字段,也称固有字段,长度为20个字节,后面的为TCP
报文的可选项和填充项,以及数据位。
暂时先写到这里,内容太多,一次讲不完,下次再继续更新。