Linux 网络编程学习笔记——一、TCP/IP 协议族

目录

一、TCP/IP 协议族体系结构以及主要协议

Linux 网络编程学习笔记——一、TCP/IP 协议族_第1张图片

1. 数据链路层

数据链路层实现了网卡接口的网络驱动程序,以处理数据在物理媒介(以太网、令牌环等)上的传输,不同的物理网络具有不同的电气特性,网络驱动程序隐藏了这些细节,为上层协议提供一个统一的接口。最常用的协议是 ARP(Address Resolve Protocol,地址解析协议)和 RARP(Reverse Address Resolve Protocol),它们实现了 IP 地址和机器物理地址(通常是 MAC 地址)之间的相互转换。

  • ARP:网络层使用 IP 地址,数据链路层使用物理地址,因此网络层必须先将目标机器的 IP 地址转化成其物理地址,才能使用数据链路层提供的服务。
  • RARP:仅用于网络上的某些无盘工作站,这些站点由于缺乏存储设备,因此无法记住自己的 IP 地址,但可以利用网卡上的物理地址来向网络管理者查询自身的 IP 地址。运行 RARP 服务器的网络管理者通常存有该网络上所有机器的物理地址到 IP 地址的映射。

2. 网络层

网络层实现数据包的选路和转发,WAN(Wide Area Network,广域网)通常使用众多分级的路由器来连接分散的主机或 LAN(Local Area Network,局域网),因此通信的两台主机一般不是直接相连的,而是通过多个中间节点(路由器)连接的。网络层的任务就是选择这些中间节点,以确定两台主机之间的通信路径。同时,网络层对上层协议隐藏了网络拓扑连接的细节,使得在传输层和网络应用程序看来,通信的双方是直接相连的。最常用的协议是 IP(Internet Protocol,因特网协议)和 ICMP(Internet Control Message Protocol,因特网控制报文协议)。

  • IP :能够根据数据包的目的 IP 地址来决定如何投递(直接交付 or 寻找下一跳路由器);
  • ICMP :它是 IP 协议的重要补充,主要用于检测网络连接。

3. 传输层

传输层为两台主机上的应用程序提供端到端(end to end)的通信,只关心通信的起始端和目的端,而不在乎数据包的中转过程,下图中实线表示实际通信过程,虚线表示逻辑通信过程:
Linux 网络编程学习笔记——一、TCP/IP 协议族_第2张图片
传输层有 3 个重要协议:

  • TCP(Transmission Control Protocol,传输控制协议):为应用提供可靠的、面向连接的和基于流(stream)的服务。
  • UDP(User Datagram Protocol,用户数据报协议):为应用提供不可靠、无连接和基于数据包的服务。
  • SCTP(Stream Control Transmission Protocol,流控制传输协议):为在因特网上传输电话信号而设计的协议,暂不讨论。

4. 应用层

应用层负责处理应用程序的逻辑,前四层均负责处理网络通信细节。应用层协议或程序可能跳过传输层直接使用网络层提供的服务,该层主要的协议有:

  • ping :是一个应用程序而不是协议,利用 ICMP ;
  • telnet :远程登录协议;
  • OSPF(Open Shortest Path First,开放最短路径优先):是一个动态路由更新协议,用于路由器之间的通信;
  • DNS(Domain Name Service,域名服务):提供机器域名到 IP 地址的转换。

二、封装

上层协议要使用下层协议提供的服务,就需要下层协议通过封装来实现:
Linux 网络编程学习笔记——一、TCP/IP 协议族_第3张图片
经过 TCP 封装后的数据称为 TCP 报文段(TCP message segment),简称 TCP 段。由于 TCP 协议为通信双方维持一个连接,并且在内核中存储相关数据,这部分数据中的 TCP 头部信息和 TCP 内核缓冲区(发送缓冲区或接收缓冲区)数据一起构成了 TCP 报文段,如下图虚线框:
Linux 网络编程学习笔记——一、TCP/IP 协议族_第4张图片
当发送端应用程序使用 send(或者 write)函数向一个 TCP 连接写入数据时,内核中的 TCP 模块首先把这些数据复制到与该连接对应的 TCP 内核发送缓冲区中,然后 TCP 模块调用 IP 模块提供的服务,传递的参数包括 TCP 头部信息和 TCP 发送缓冲区的数据。

经过 UDP 封装后的数据称为 UDP 数据包(UDP datagram),它无需为应用层数据保存副本,当一个 UDP 数据包被成功发送后,UDP 内核缓冲区中的该数据包就被丢弃。如果应用程序检测到该数据报未能被接收端正确接收,并打算重发,则需要从用户空间将该数据报拷贝到 UDP 内核发送缓冲区中。

经过 IP 封装后的数据称为 IP 数据包(IP datagram),包括头部信息和数据信息两部分,其中数据部分就是应用层的数据报。

经过数据链路层封装的数据称为帧(frame),传递媒介不同,帧的类型也不同。帧的最大传输单元(Max Transmit Unit,MTU),即最多能携带多少上层协议数据,通常受到网络类型的限制,因此过长的 IP 数据报需要被分片(fragment)传输。

三、分用

当帧到达目的主机时,将沿着协议栈自底向上依次传递,各层协议一次处理帧中本层负责的头部数据,以获取所需的信息,并最终将处理后的帧交给目标应用程序,这个过程被称为分用(demultiplexing):
Linux 网络编程学习笔记——一、TCP/IP 协议族_第5张图片
因为不同协议都在使用帧传输的数据,因此帧的头部需要提供某个字段来进行区分;同理,不同协议都在使用 IP 数据报,因此也需要提供某个字段来进行区分;同理,应用层也需要区分 TCP 数据报和 UDP 数据报。

四、ARP 协议

ARP 协议能实现任意网络层地址到任意物理地址的转换:

  • 主机向自己所在的网络广播一个 ARP 请求,请求中包含目标机器的网络地址;
  • 其他机器接收到这个请求,只有被请求的目标机器会回应一个 ARP 应答,其中包含自己的物理地址。
    Linux 网络编程学习笔记——一、TCP/IP 协议族_第6张图片
  • 硬件类型:定义物理地址的类型,1 表示 MAC 地址;
  • 协议类型:表示要映射的协议地址类型,值为 0x800 ,表示 IP 地址;
  • 硬件地址长度/协议地址长度:单位为字节,对 MAC 地址来说,长度为 6 ;对 IP 地址来说,长度为 4 ;
  • 操作:指出 4 中操作类型:
    • ARP 请求:1;
    • ARP 应答:2;
    • RARP 请求:3;
    • RARP 应答:4。
  • 最后四个地址:指定通信双方的以太网地址和 IP 地址:
    • 发送端填充除目的端以太网地址外的其他 3 个字段后进行发送;
    • 接收端发现该请求的目的端地址是自己,就把自己的以太网地址填进去,然后交换两个目的端地址和两个发送端地址并发送。

ARP 报文长 28 字节,加上以太网帧头尾的 18 字节后共有 46 字节。由于有的实现要求以太网帧数据部分长度至少为 46 字节,此时 ARP 报文将增加一些填充字节以满足要求,此时以太网帧的长度为 64 字节。

通常 ARP 维护一个高速缓存,一种包含经常访问或最近访问的机器的 IP 地址到物理地址的映射,这样就避免了重复的 ARP 请求,提高了发送数据包的速度。Linux 中可以使用 arp 命令查看和修改缓存。

五、DNS 工作原理

通常使用机器的域名而不是 IP 地址来进行访问,因此就需要使用 DNS 协议将域名转换为 IP 地址。DNS 是一套分布式的域名服务系统,每个 DNS 服务器上都存放着大量的机器名和 IP 地址的映射,并且是动态更新的。众多网络客户端程序都是用 DNS 协议来向 DNS 服务器拆线呢目标主机的 IP 地址:
Linux 网络编程学习笔记——一、TCP/IP 协议族_第7张图片

  • 16 位标识:用于标记一对 DNS 查询和应答,以此区分一个 DNS 应答是哪个 DNS 查询的回应;
  • 16 位标志:用于协商具体的通信方式和反馈通信状态:
    Linux 网络编程学习笔记——一、TCP/IP 协议族_第8张图片
    • QR:查询/应答标志,0 表示查询,1 表示应答;
    • opcode:定义查询和应答的类型,0 表示标准查询,1 表示反向查询,2 表示请求服务器状态;
    • AA:授权应答标志,仅有应答报文使用,1 表示域名服务器是授权服务器;
    • TC:截断标志,仅当 DNS 报文使用 UDP 服务时使用,1 表示报文超过 512 字节,被截断;
    • RD:递归查询标志:1 表示执行递归查询,0 表示执行迭代查询;
    • RA:允许递归标志,仅有应答报文使用,1 表示 DNS 服务器支持递归查询;
    • zero:未使用,标记为 0 ;
    • rcode,4 位返回码,表示应答的状态,0 表示无错误,3 表示域名不存在。
  • 接下来 4 个字段分别指出 DNS 报文的最后 4 个字段的资源记录数目:
    • 查询报文:包含 1 个查询问题,应答资源记录数、授权资源记录数和额外资源记录数都为 0 ;
    • 应答报文:应答资源记录数至少为 1 ,授权资源记录数和额外资源记录数可为 0 或非 0 ;
  • 查询问题:
    Linux 网络编程学习笔记——一、TCP/IP 协议族_第9张图片
    • 查询名:以一定的格式封装了要查询的主机域名;
    • 16 位查询类型:表示如何执行查询操作:
      • 类型 A ,值是 1 ,表示获取目标主机的 IP 地址;
      • 类型 CNAME ,值是 5 ,表示获得目标主机的别名;
      • 类型 PTR ,值是 12 ,表示反向查询。
    • 16 位查询类:通常为 1 ,表示获取因特网地址(IP 地址);
  • 应答、授权、额外:
    Linux 网络编程学习笔记——一、TCP/IP 协议族_第10张图片
    • 32 位域名:记录中与资源对应的名字,其格式和查询问题中的查询名字段相同;
    • 16 位类型、16 位类:与 DNS 查询问题的对应字段相同;
    • 32 位生存时间:表示该查询记录结果可被本地客户端程序缓存多长时间,单位为秒;
    • 16 位资源数据长度、资源数据:内容取决于类型字段,对类型 A 而言,资源数据是 32 位的 IPv4 地址,而资源数据长度则为 4 字节。

六、socket

数据链路层、网络层、传输层协议是在内核中实现的,因此操作系统需要实现一组系统调用,使得应用程序能够访问这些协议提供的服务。实现这组系统调用的 API(Application Programming Interface,应用程序编程接口)主要有两套:socket 和 XTI ,后者基本不再使用。由 socket 定义的这一组 API 提供两个功能:

  • 将应用程序数据从用户缓冲区中复制到 TCP/UDP 内核发送缓冲区,以交付内核来发送数据,或者是从内核 TCP/UDP 接收缓冲区中复制数据到用户缓冲区,以读取数据;
  • 应用程序可以通过它们来修改内核中各层协议的某些头部信息或其他数据结构,从而精细地控制底层通信的行为。

socket 是一套通用网络编程接口,它不但可以访问内核中 TCP/IP 协议栈,而且可以访问其他网络协议栈。

你可能感兴趣的:(计算机网络,网络,linux,tcp/ip)