包的基本知识

TCP模块在执行连接、收发、断开等各阶段操作时,都需要委托IP模块将数据封装成包发送给通信对象。我们在TCP的讲解中也经常提到IP,下面就来讨论一下IP模块是如何将包发送给对方的

正式开始这个话题之前,我们先来介绍一下关于网络包的一些基本知识。首先,包是由头部和数据两部分构成的(图2.14(a))。头部包含目的地址等控制信息,大家可以把它理解为快递包裹的面单;头部后面就是委托方要发送给对方的数据,也就相当于快递包裹里的货物。一个包发往目的地的过程如图2.15所示。

首先,发送方的网络设备会负责创建包,创建包的过程就是生成含有正确控制信息的头部,然后再附加上要发送的数据。接下来,包会被发往最近的网络转发设备。当到达最近的转发设备之后,转发设备会根据头部中的信息判断接下来应该发往哪里。这个过程需要用到一张表,这张表里面记录了每一个地址对应的发送方向,也就是按照头部里记录的目的地址在表里进行查询,并根据查到的信息判断接下来应该发往哪个方向。比如,如果查表的结果是“目标地址为××××的包应该发到××××号线路”,那么转发设备就会把这个包发到××××号线路去。接下来,包在向目的地移动的过程中,又会到达下一个转发设备,然后又会按照同样的方式被发往下一个转发设备。就这样,经过多个转发设备的接力之后,包最终就会到达接收方的网络设备。当然,发送方向接收方发送一个包,接收方可能也会向发送方返回一个包,此时的发送方到了接下来的某个时刻就会变成接收方。因此,我们不需要把发送方和接收方明确区分开来,在这里我们把发送方和接收方统称为终端节点


前面介绍的这些基本知识,对于各种通信方式都是适用的,当然也适用于TCP/IP网络。不过,TCP/IP包的结构是在这个基本结构的基础上扩展出来的,因此更加复杂。在第1章1.2.1节,我们讲过子网的概念,还讲过网络中有路由器和集线器两种不同的转发设备,它们在传输网络包时有着各自的分工。

(1)路由器根据目标地址判断下一个路由器的位置
(2)集线器在子网中将网络包传输到下一个路由

实际上,集线器是按照以太网规则传输包的设备,而路由器是按照IP规则传输包的设备,因此我们也可以作如下理解。

(1)IP协议根据目标地址判断下一个IP转发设备的位置
(2)子网中的以太网协议将包传输到下一个转发设备

具体来说,如图2.14(b)所示,TCP/IP包包含如下两个头部。

(a)MAC头部(用于以太网协议)
(b)IP头部(用于IP协议)

这两个头部分别具有不同的作用。首先,发送方将包的目的地,也就是要访问的服务器的IP地址写入IP头部中。这样一来,我们就知道这个包应该发往哪里,IP协议就可以根据这一地址查找包的传输方向,从而找到下一个路由器的位置,也就是图2.16中的路由器R1。接下来,IP协议会委托以太网协议将包传输过去。这时,IP协议会查找下一个路由器的以太网地址(MAC地址),并将这个地址写入MAC头部中。这样一来,以太网协议就知道要将这个包发到哪一个路由器上了。

网络包在传输过程中(图2.16①)会经过集线器,集线器是根据以太网协议工作的设备。为了判断包接下来应该向什么地方传输,集线器里有一张表(用于以太网协议的表),可根据以太网头部中记录的目的地信息查出相应的传输方向。这张图中只有一个集线器,当存在多个集线器时,网络包会按顺序逐一通过这些集线器进行传输。

接下来,包会到达下一个路由器(图2.16②)。路由器中有一张IP协议的表,可根据这张表以及IP头部中记录的目的地信息查出接下来应该发往哪个路由器。为了将包发到下一个路由器,我们还需要查出下一个路由器的MAC地址,并记录到MAC头部中,大家可以理解为改写了MAC头部。这样,网络包就又被发往下一个节点了。

再往后的过程图上就没有画出来了。网络包会通过路由器到达下一个路由器R2。这个过程不断重复,最终网络包就会被送到目的地,当目的地设备成功接收之后,网络包的传输过程就结束了。

前面介绍的就是在TCP/IP网络中,一个网络包从出发到到达目的地的全过程。虽然看起来有点复杂,不过设计这样的分工是有原因的。前面讲了IP和以太网的分工,其中以太网的部分也可以替换成其他的东西,例如无线局域网、ADSL、FTTH等,它们都可以替代以太网的角色帮助IP协议来传输网络包。因此,将IP和负责传输的网络分开,可以更好地根据需要使用各种通信技术。像互联网这样庞大复杂的网络,在架构上需要保证灵活性,这就是设计这种分工方式的原因。

包收发操作概览

了解了整体流程之后,下面来讲一讲在协议栈中IP模块是如何完成包收发操作的。尽管我们说IP模块负责将包发给对方,但实际上将包从发送方传输到接收方的工作是由集线器、路由器等网络设备来完成的,因此IP模块仅仅是整个包传输过程的入口而已。即便如此,IP模块还是有很多工作需要完成,首先我们先粗略地整理一下。

包收发操作的起点是TCP模块委托IP模块发送包的操作(图2.17中的“①发送”)。这个委托的过程就是TCP模块在数据块的前面加上TCP头部,然后整个传递给IP模块,这部分就是网络包的内容。与此同时,TCP模块还需要指定通信对象的IP地址,也就是需要写清楚“将什么内容发给谁”。


收到委托后,IP模块会将包的内容当作一整块数据,在前面加上包含控制信息的头部。刚才我们讲过,IP模块会添加IP头部和MAC头部这两种头部。IP头部中包含IP协议规定的、根据IP地址将包发往目的地所需的控制信息;MAC头部包含通过以太网的局域网将包传输至最近的路由器所需的控制信息。关于IP头部和MAC头部的区别以及其中包含的控制信息的含义,我们将稍后介绍。总之,加上这两个头部之后,一个包就封装好了,这些就是IP模块负责的工作。

IP模块负责添加如下两个头部。
(1) MAC头部:以太网用的头部,包含MAC地址
(2)IP头部:IP用的头部,包含IP地址

接下来,封装好的包会被交给网络硬件(图2.17中的“②发送”),例如以太网、无线局域网等。网络硬件可能是插在计算机主板上的板卡,也可能是笔记本电脑上的PCMCIA卡,或者是计算机主板上集成的芯片,不同形态的硬件名字也不一样,本书将它们统称为网卡。传递给网卡的网络包是由一连串0和1组成的数字信息,网卡会将这些数字信息转换为电信号或光信号,并通过网线(或光纤)发送出去,然后这些信号就会到达集线器、路由器等转发设备,再由转发设备一步一步地送达接收方。

包送达对方之后,对方会作出响应。返回的包也会通过转发设备发送回来,然后我们需要接收这个包。接收的过程和发送的过程是相反的,信息先以电信号的形式从网线传输进来,然后由网卡将其转换为数字信息并传递给IP模块(图2.17中的“③接收”)。接下来,IP模块会将MAC头部和IP头部后面的内容,也就是TCP头部加上数据块,传递给TCP模块。接下来的操作就是我们之前讲过的TCP模块负责的部分了。

在这个过程中,有几个关键的点。TCP模块在收发数据时会分为好几个阶段,并为各个阶段设计了实现相应功能的网络包,但IP的包收发操作都是相同的,并不会因包本身而有所区别。因为IP模块会将TCP头部和数据块看作一整块二进制数据,在执行收发操作时并不关心其中的内容,也不关心这个包是包含TCP头部和数据两者都有呢,还是只有TCP头部而没有数据。当然,IP模块也不关心TCP的操作阶段,对于包的乱序和丢失也一概不知。总之,IP的职责就是将委托的东西打包送到对方手里,或者是将对方送来的包接收下来,仅此而已。因此,接下来我们要讲的这些关于IP的工作方式,可适用于任何TCP委派的收发操作。

无论要收发的包是控制包还是数据包,IP对各种类型的包的收发操作都是相同的。

生成包含接收方IP地址的IP头部

下面来看一看IP模块的具体工作过程。IP模块接受TCP模块的委托负责包的收发工作,它会生成IP头部并附加在TCP头部前面。IP头部包含的内容如表2.2所示,其中最重要的内容就是IP地址,它表示这个包应该发到哪里去。这个地址是由TCP模块告知的,而TCP又是在执行连接操作时从应用程序那里获得这个地址的,因此这个地址的最初来源就是应用程序。IP不会自行判断包的目的地,而是将包发往应用程序指定的接收方,即便应用程序指定了错误的IP地址,IP模块也只能照做。当然,这样做肯定会出错,但这个责任应该由应用程序来承担。


IP头部中还需要填写发送方的IP地址,大家可以认为是发送方计算机的IP地址,实际上“计算机的IP地址”这种说法并不准确。一般的客户端计算机上只有一块网卡,因此也就只有一个IP地址,这种情况下我们可以认为这个IP地址就是计算机的IP地址,但如果计算机上有多个网卡,情况就没那么简单了。IP地址实际上并不是分配给计算机的,而是分配给网卡的,因此当计算机上存在多块网卡时,每一块网卡都会有自己的IP地址。很多服务器上都会安装多块网卡,这时一台计算机就有多个IP地址,在填写发送方IP地址时就需要判断到底应该填写哪个地址。这个判断相当于在多块网卡中判断应该使用哪一块网卡来发送这个包,也就相当于判断应该把包发往哪个路由器,因此只要确定了目标路由器,也就确定了应该使用哪块网卡,也就确定了发送方的IP地址。

IP头部的“接收方IP地址”填写通信对象的IP地址。
发送方IP地址需要判断发送所使用的网卡,并填写该网卡的IP地址。

那么,我们应该如何判断应该把包交给哪块网卡呢?其实和图2.16中路由器使用IP表判断下一个路由器位置的操作是一样的。因为协议栈的IP模块与路由器中负责包收发的部分都是根据IP协议规则来进行包收发操作的,所以它们也都用相同的方法来判断把包发送给谁。

这个“IP表”叫作路由表[插图],我们将在第3章探索路由器时详细介绍它的用法,这里先简单讲个大概。如图2.18所示,我们可以通过route print命令来显示路由表,下面来边看边讲。首先,我们对套接字中记录的目的地IP地址与路由表左侧的Network Destination栏进行比较,找到对应的一行。例如,TCP模块告知的目标IP地址为192.168.1.21,那么就对应图2.18中的第6行,因为它和192.168.1的部分相匹配。如果目标IP地址为10.10.1.166,那么就和10.10.1的部分相匹配,所以对应第3行。以此类推,我们需要找到与IP地址左边部分相匹配的条目[插图],找到相应的条目之后,接下来看从右边数第2列和第3列的内容。右起第2列,也就是Interface列,表示网卡等网络接口,这些网络接口可以将包发送给通信对象。此外,右起第3列,即Gateway列表示下一个路由器的IP地址,将包发给这个IP地址,该地址对应的路由器[插图]就会将包转发到目标地址[插图]。路由表的第1行中,目标地址和子网掩码[插图]都是0.0.0.0,这表示默认网关,如果其他所有条目都无法匹配,就会自动匹配这一行[插图]。

这样一来,我们就可以判断出应该使用哪块网卡来发送包了,然后就可以在IP头部的发送方IP地址中填上这块网卡对应的IP地址。

接下来还需要填写协议号,它表示包的内容是来自哪个模块的。例如,如果是TCP模块委托的内容,则设置为06(十六进制),如果是UDP模块委托的内容,则设置为17(十六进制),这些值都是按照规则来设置的。在现在我们使用的浏览器中,HTTP请求消息都是通过TCP来传输的,因此这里就会填写表示TCP的06(十六进制)。其他字段内也需要填写相应的值,但对大局没什么影响,我们会在第3章进行介绍,这里就先省略了。

生成以太网用的MAC头部

生成了IP头部之后,接下来IP模块还需要在IP头部的前面加上MAC头部(表2.3)。IP头部中的接收方IP地址表示网络包的目的地,通过这个地址我们就可以判断要将包发到哪里,但在以太网的世界中,TCP/IP的这个思路是行不通的。以太网在判断网络包目的地时和TCP/IP的方式不同,因此必须采用相匹配的方式才能在以太网中将包发往目的地,而MAC头部就是干这个用的。

IP模块在生成IP头部之后,会在它前面再加上MAC头部。MAC头部是以太网使用的头部,它包含了接收方和发送方的MAC地址等信息。

关于以太网的结构我们稍后会进行介绍,但下面的内容需要一些MAC头部的相关知识才能理解,因此先介绍一些最基础的。MAC头部的开头是接收方和发送方的MAC地址,大家可以认为它们和IP头部中的接收方和发送方IP地址的功能差不多,只不过IP地址的长度为32比特,而MAC地址为48比特。此外,IP地址是类似多少弄多少号这种现实中地址的层次化的结构,而MAC地址中的48比特可以看作是一个整体。尽管有上述差异,但从表示接收方和发送方的意义上来说,MAC地址和IP地址是没有区别的,因此大家可以暂且先把它们当成是一回事。第3个以太类型字段和IP头部中的协议号类似。在IP中,协议号表示IP头部后面的包内容的类型;而在以太网中,我们可以认为以太网类型后面就是以太网包的内容,而以太类型就表示后面内容的类型。以太网包的内容可以是IP、ARP等协议的包,它们都有对应的值,这也是根据规则来确定的[插图]。

在生成MAC头部时,只要设置表2.3中的3个字段就可以了。方便起见,我们按照从下往上的顺序来对表进行讲解。首先是“以太类型”,这里填写表示IP协议的值0800(十六进制)。接下来是发送方MAC地址,这里填写网卡本身的MAC地址。MAC地址是在网卡生产时写入ROM里的,只要将这个值读取出来写入MAC头部就可以了[插图]。对于多块网卡的情况,请大家回想一下设置发送方IP地址的方法[插图]。设置发送方IP地址时,我们已经判断出了从哪块网卡发送这个包,那么现在只要将这块网卡对应的MAC地址填进去就好了。

前面这些还比较简单,而接收方MAC地址就有点复杂了。只要告诉以太网对方的MAC的地址,以太网就会帮我们把包发送过去,那么很显然这里应该填写对方的MAC地址。然而,在这个时间点上,我们还没有把包发送出去,所以先得搞清楚应该把包发给谁,这个只要查一下路由表就知道了。在路由表中找到相匹配的条目,然后把包发给Gateway列中的IP地址就可以了。

既然已经知道了包应该发给谁,那么只要将对方的MAC地址填上去就好了,但到这里为止根本没有出现对方的MAC地址,也就是说我们现在根本不知道对方的MAC地址是什么。因此,我们还需要执行根据IP地址查询MAC地址的操作。

IP模块根据路由表Gateway栏的内容判断应该把包发送给谁。

IP与以太网的包收发操作相关推荐

  1. shell获取多张网卡对应的ip_网络是怎样连接的 -- IP与以太网的收发操作

    TCP模块在执行连接.收发.断开等各阶段操作时,都需要委托IP模块将数据封装成包发送给通信对象. 包的基本知识 包是由头部和数据两部分构成的.头部包含目的地址等控制信息,可以理解为快递包裹的面单:头部 ...

  2. 网络数据包收发流程(三):e1000网卡和DMA

    早就想整理网络数据包收发流程了,一直太懒没动笔.今天下决心写了 一.硬件环境 intel82546:PHY与MAC集成在一起的PCI网卡芯片,很强大 bcm5461:   PHY芯片,与之对应的MAC ...

  3. 【STM32学习】——USART串口数据包HEX/文本数据包收发流程串口收发HEX/文本数据包实操

    文章目录 前言 一.数据包格式(江科大规定) 1.HEX数据包 2.文本数据包 3.两者对比 二.数据包收发流程 1.HEX数据包接收(只演示固定包长) 2.文本数据包接收(只演示可变包长) 三.实操 ...

  4. PPP IP 、以太网IP及无线局域网IP分析

    一般查询本机的IP地址是通过在CMD中运行:"ipconfig/all"命令来得到,如下图所示: 发现不止一个IPV4地址,有PPP适配器的IP.无线局域网适配器WLAN的IP.以 ...

  5. java udp包_基于UDP协议的数据包收发程序(代码+报告)Java

    [实例简介] 设计要求: 1)按照UDP协议数据包发送方式实现用户端之间的通信. 2)统计包的发送和接收数,计算数据包的丢失数. 3)设计美观易用的图形界面. [实例截图] [核心代码] 基于UDP协 ...

  6. W5500全硬件 TCP/IP 嵌入式以太网控制器WIZNET

    概述 W5500 是一款全硬件 TCP/IP 嵌入式以太网控制器,为嵌入式系统提供了更加简易的互联网连接方案. W5500 集成了 TCP/IP 协议栈,10/100M 以太网数据链路层(MAC)及物 ...

  7. Wiznet W5100硬件TCP/IP嵌入式以太网控制器

    WIZnet 的W5100硬件TCP/IP嵌入式以太网控制器是一个功能齐全的.单芯片的.因特网驱动的10/100以太网控制器.嵌入式应用需要易于集成.稳定.性能.空间.系统成本控制而W5100就是为嵌 ...

  8. 微信朋友圈“文字发”操作技巧,轻松实现不带图发布

    微信朋友圈"文字"操作技巧,轻松实现不带图发布 微信朋友圈作为一款非常受欢迎的社交软件,不仅可以让我们方便地分享照片.视频等内容,还可以通过文字来表达自己的想法和感受.但是,有时候 ...

  9. Eth08-EthCtrlConfig:以太网控制器的硬件操作的timeout值配置

    文章目录 1 EthCtrlConfig:以太网控制器的硬件操作的timeout值配置 传送门 ==>> AutoSAR入门和实战系列总目录 1 EthCtrlConfig:以太网控制器的 ...

最新文章

  1. python表达式3and not5的值_太原理工大学python考试题总结
  2. 自学编程是从python语言还是c语言开始-非计算机专业大学生想自学编程应该学C语言还是学Python?...
  3. 1086 就不告诉你 (15 分)—PAT (Basic Level) Practice (中文)
  4. 学习vim: 常用命令
  5. 0+到10+随机数+java_Java随机数总结
  6. hrm系统源码php,悟空HRM下载_悟空HRM0.1开源版 - 系统之家
  7. 服务器系统还原后如何退回去,如何进行系统还原
  8. Java SE学习练习题--IO、List 配合使用
  9. PS--给图片加水印技巧
  10. 计算机运行快是取决什么,电脑速度快慢取决哪个硬件
  11. 【C语言】操作符详解
  12. 信息化15年规划推动中国信息化步入深水区
  13. 基于聚类算法的城市餐饮数据分析与店铺选址
  14. Ubuntu安装搜狗输入法后修改默认英文输入状态的方法
  15. 1.1需求调研(一) - 需求调研的目的
  16. 北邮计算机学院国家示范,北京邮电大学获批2020年国家自然科学基金81项
  17. 2018年,如下几件事或许值得期待
  18. DASH( Dynamic Adaptive Streaming over HTTP )协议
  19. 计算机软件工程考研考哪些专业,软件工程考研考什么科目?
  20. [NLP] 实例讲解 N-gram语言模型 中 Good-Turning 平滑技术

热门文章

  1. linux学习笔记:shell变量
  2. Python求1~300之间所有的完数
  3. python怎么更改背景颜色_python中绘图时怎么改背景颜色?
  4. arch linux编译,ArchLinux内核编译与安装
  5. php安装包进行安装吗,php的一键安装包有哪些php环境搭建
  6. matlab线检测,车道线检测(matlab)
  7. python导入requests库_windows环境中python导入requests
  8. laytpl语法_浅谈laytpl 模板空值显示null的解决方法及简单的js表达式
  9. Eclipse修改svn地址
  10. 北京大学生物信息学学习(3动态规划进行2序列比对的原理 )