数据链路层实现网卡接口的网络驱动程序,以处理数据在物理媒介上的传输。不同的物理网络有不同的电器特性,网络驱动程序隐藏了这些细节,为上层协议提供一个统一的接口。
数据链路层两个常用的协议是ARP协议(Address Resolution Protocol,地址解析协议)和RARP协议(Reverse Address Resolution Protocol,反向地址解析解析)。它们实现了IP地址和物理地址之间的相互转换。
网络层使用IP地址寻址一台机器,而数据链路层使用物理地址寻址一台机器,因此网络层必须先将其目标机器IP地址转换为物理地址,才能使用数据链路层提供的服务。
其工作原理是:主机向自己所在的网络广播-个ARP请求,该请求包含目标机器的网络地址。此网络上的其他机器都将收到这个请求,但只有被请求的目标机器会回应-一个 ARP应答,其中包含自己的物理地址。
由此可知,ARP请求/应答报文的长度为28字节。如果再加上以太网帧头部和尾部的18字节,则一个搒带ARP请求1应答报文的以太网帧长度为46字节。不过有的实现要求以太网帧数据部分长度至少为46字节,此时ARP请求/应答报文将增加一-些填充字节,以满足这个要求。在这种情况下,一个携带ARP请求/应答报文的以太网帧长度为64字节。
通常,ARP 维护-一个高速缓存,其中包含经常访问(比如网关地址)或最近访问的机器的IP地址到物理地址的映射。这样就避免了重复的ARP请求,提高了发送数据包的速度。
cmf@cmf-virtual-machine:~$ arp -a localhost (192.168.26.254) 位于 00:50:56:e3:1f:1d [ether] 在 ens33 localhost (192.168.26.2) 位于 00:50:56:ea:fc:36 [ether] 在 ens33 localhost (192.168.26.1) 位于 00:50:56:c0:00:08 [ether] 在 ens33 ? (169.254.169.254) 位于 <incomplete> 在 ens33
网络层实现数据包的选择和转发。
IP协议根据数据报的目的IP地址来决定如何投递它。如果数据包不能直接发给目标主机,那么IP协议就为他寻找一个合适的下一跳(next hop)路由器,并将数据包交付给路由来器转发。多次重复这一过程,最终到达目标主机,或者由于发送失败而被丢弃。
ICMP协议(Internet Control Message Protocol,因特网控制报文协议)它是IP协议的补充,主要用于网络连接测试。
8位类型字段用于区分报文类型,它将ICMP分为两大类:
有的 ICMP报文还是用8为代码字段来进一步细分不同的条件。比如重定向报文使用代码值0表示对网路重定向,代码值1表示对主机重定向。
ICMP使用16位校验和字段对整个报文(包括头部和内容部分)进行循环冗余校验(Cyclic Redundancy Check, CRC)以校验报文在传输过程中是否损坏。不同的ICMP报文类型有不同的正文内容。
传输层为两台主机上的应用程序提供端到端的通信。与网络层使用的逐跳通信方式不同,传输层只关心通信的起始端和目的端,而不在乎数据包的中转过程。
垂直的直线箭头表示TCP/IP协议族各层之间的实体通信,而水平的虚线箭头表示逻辑通信线路。从中可见,数据链路层封装了物理网络的电气细节;网络层封装了网络连接的细节;传输层则为程序封装了一条端到端的逻辑通信链路,它负责数据的收发,链路的超时重连等;
TCP协议(TCP,Transmission Control Protocol,传输控制协议)它为应用层提供面向连接的、可靠的、基于字节流的服务。
UDP协议(UDP,User Datagram Protocol,用户数据报协议)它为应用层提供无连接,不可靠,基于数据报的服务。
SCTP协议(SCTP,Stream Control Transmission Protocol,流控制传输协议)是一种传输协议,在TCP/IP协议栈中所处的位置和TCP、UDP类似,兼有TCP/UDP两者特征
应用层负责处理应用程序的逻辑。数据链路层、网络层和传输层负责处理网络通信细节,这部分必须既稳定又高效,因此它们都在内核空间中实现。而应用层则在用户空间实现,因为它负责处理众多逻辑,比如文件传输、名称查询和网络管理等。如果应用层也在内核中实现,则会使内核变得非常庞大。当然,也有少数服务器程序是在内核中实现的,这样代码就无须在用户空间和内核空间来回切换(主要是数据的复制),极大地提高了工作效率。不过这种代码实现起来较复杂,不够灵活,且不便于移植。
应用层协议(或程序)可能跳过传输层直接使用网络层提供的服务,比如ping程序和OSPF协议。应用层协议(或程序)通常既可以使用TCP服务,又可以使用UDP服务,比如DNS协议。我们可以通过/etc/services文件查看所有知名的应用层协议,以及它们都能使那些传输层服务。
DNS是--套分布式的域名服务系统。每个DNS服务器上都存放着大量的机器名和IP地址的映射,并且是动态更新的。众多网络客户端程序都使用DNS协议来向DNS服务器查询目标主机的IP地址。DNS查询和应答报文的格式如图。
16位标识e字段用于标记- -对 DNS查询和应答,以此区分-一个DNS应答是哪个DNS查询的回应。16位标志字段用于协商具体的通信方式和反馈通信状态。
接下来的4个字段则分别指出DNS报文的最后4个字段的资源记录数目。对查询报文而言,它一般包含1个查询问题,而应答资源记录数、授权资源记录数和额外资源记录数则为0。应答报文的应答资源记录数则至少为1,而授权资源记录数和额外资源记录数可为0或非0。
查询类型的格式:
查询名以一定的格式封装了要查询的主机域名。16位查询类型表示如何执
查询操作,常见的类型有如下几种:
16位查询类通常为1,表示获取因特网地址(IP 地址)。
应答字段、授权字段和额外信息字段都使用资源记录(Resource Record,RR)格式。资源记录格式如图所示。
32 位域名是该记录中与资源对应的名字,其格式和查询问题中的查询名字
段相同。16 位类型和16位类字段的含义也与DNS查询问题的对应字段相同。
32位生存时间表示该查询记录结果可被本地客户端程序缓存多长时间,单位是秒。
16位资源数据长度字段和资源数据字段的内容取决于类型字段。对类型A而言,资源数据是32位的IPv4地址,而资源数据长度则为4 (以字节为单位)。
通过封装(encapsulation)上层协议可以使用下层协议提供的服务。应用程序数据在发送到物理网络上之前,将沿着协议栈从上往下依次传递。每层协议都将在上层数据的基础上加上自己的头部信息(有时还包括尾部信息),以实现该层的功能。
经过TCP封装后的数据称为TCP报文段(TCP message segment),或者简称TCP段。TCP协议为通信双方维持一个连接,并且在内核中存储相关数据。这部分数据中的TCP头部信息和TCP内核缓冲区(发送缓冲区或接收缓冲区)数据一起构成了 TCP报文段。
当发送端应用程序使用send (或者write)丽数向-一个TCP连接写人数据时,内核中的TCP模块首先把这些数据复制到与该连接对应的TCP内核发送缓冲区中,然后TCP模块调用IP模块提供的服务,传递的参数包括TCP头部信息和TCP发送缓冲区中的数据,即TCP报文段。
经过UDP封装后的数据称为UDP数据报(UDPdatagram)。UDP对应用程序数据的封装与TCP类似。不同的是,UDP无须为应用层数据保存副本,因为它提供的服务是不可靠的。当一个UDP数据报被成功发送之后,UDP内核缓冲区中的该数据报就被丢弃了。如果应用程序检测到该数据报未能被接收端正确接收,并打算重发这个数据报,则应用程序需要重新从用户空间将该数据报拷贝到UDP内核发送缓冲区中。
经过IP封装后的数据称为IP数据报(IP datagram)。IP 数据报也包括头部信息和数据部分,其中数据部分就是一个TCP报文段、UDP数据报或者ICMP报文。
经过数据链路层封装的数据称为帧(frame)。传输媒介不同,帧的类型也不同。比如,以太网上传输的是以太网帧(ethernet frame),而令牌环网络上传输的则是令牌环帧(token ring frame)。以以太网帧为例。
以太网帧使用6字节的目的物理地址和6字节的源物理地址来表示通信的双方。关于类型(type)字段,4字节CRC字段对帧的其他部分提供循环冗余校验。
帧的最大传输单元(Max Transmit Unit, MTU),即帧最多能携带多少上层协议数据(比如IP数据报),通常受到网络类型的限制。图1-6所示的以太网帧的MTU是1500字节。正因为如此,过长的IP数据报可能需要被分片( fragment)传输。帧才是最终在物理网络上传送的字节序列。至此,封装过程完成。
当帧到达目标主机时,将沿着协议栈自低向上依次传递,各层协议依次处理帧中本次负责的头部数据,以获取所需的信息,并最终将处理后的帧交给目标应用程序。这个过程称为分用((demultiplexing)。 分用是依靠头部信息中的类型字段实现的。