TCP/IP详解 卷1:协议 学习笔记 第三章 IP:网际协议
所有TCP、UDP、ICMP、IGMP数据都以IP数据报格式传输。
IP提供不可靠、无连接的数据报传送服务:
1.不可靠:不保证IP数据报能成功到达目的地。它仅提供最好的传输服务。发生某种错误(如路由器暂时用完了缓冲区)时,丢弃该数据报,然后发送ICMP消息报给源端。可靠性要由上层(如TCP)提供。
2.无连接:IP不维护任何关于后续数据报的状态信息。每个数据报的处理是相互独立的。即IP数据报可以不按发送顺序接收。
IP数据报首部有20字节,传输顺序每行是从0bit~31bit,这种传输次序称作big endian字节序(低位存高位数字,如首部长字段为1110,在最高位存1,此时它的值为14)。又由于TCP/IP首部中所有二进制整数在网络中都要求以这种次序传输,因此它又称为网络字节序。以其他形式存储二进制整数的机器,如little endian格式,必须在传输数据之前把首部转换成网络字节序。
目前的协议版本号是4,因此IP有时也称作IPv4。
首部长度指首部有多少32bit字,是上图中全部字段的长度和。由于它是长为4bit的字段,因此IP首部最长60字节(4比特最多表示15,15*32bit=60字节)。普通IP数据报(仅有固定长度)该字段值为5。
服务类型(TOS)字段包括一个3bit的优先权子字段(现已被忽略),4bit的TOS子字段,1bit必须置0的未用位。4bit的TOS子字段中每一bit分别代表:最小时延、最大吞吐量、最高可靠性、最小费用,4bit中只能置位其中1bit,如果4bit都为0,代表其是一般服务。
Telnet和Rlogin两个交互应用主要用来传少量交互数据,因此要求最小时延。FTP文件传输要求有最大吞吐量。网络管理(SNMP)和路由选择协议是最高可靠性。用户网络新闻(Usenet news,NNTP)是唯一要求最小费用的应用。
现在大多TCP/IP都不支持TOS特性,但自4.3BSD Reno以后的新版系统都对它进行了设置。新的路由协议如OSPF、IS-IS能根据这些字段值进行路由决策。
SLIP一般提供基于服务类型的排队方法,以允许交互通信数据在处理大块数据之前进行处理,由于大多实现都不使用TOS字段,因此这种排队机制必须由SLIP自己判断和处理,驱动先查看协议字段(确定是否是TCP段),然后检查TCP信源和信宿的端口号,以判断是否是一个交互服务,一个驱动程序的注释写道这种判断方法是“令人厌恶的处理方法”,但这是必须的,因为很多实现不允许应用设置TOS字段。
总长度字段指整个IP数据报的长度(包括首部),以字节为单位,利用首部长度字段和总长度字段,可以知道IP数据报中数据内容的起始位置和长度。该字段长16bit,所以IP数据报最长65535字节,超级通道的MTU就是65535,使用了最长的IP数据报。当数据报被分片时,该字段的值也随着变化。
尽管可以传65535字节的IP数据报,但大多链路层都会对它分片,而且主机要求不能接收超过576字节的数据,由于TCP把用户数据分为若干片,因此一般这个限制不会影响TCP。大量使用UDP的应用如RIP(Routing Information Protocol,路由信息协议)、TFTP、BOOTP(被称为引导程序协议或自举协议)、DNS(被称为域名系统(服务)协议)和SNMP(简单网络管理协议),都限制用户数据报长度为512字节,这小于576字节。但大多实现,特别是支持NFS(网络文件系统)的,都允许超过8192字节的IP数据报。
总长度字段是IP首部中必要内容,因为一些数据链路(如以太网)需要填充一些数据以达到最小长度,根据总长可以知道填充了多少字节。
标识字段唯一地标识主机发送的每一份数据报,通常每发送一份报文它的值就加1。
TTL(time-to-live)生存时间字段设置了数据报可以经过的最多路由器数。它由源主机设置(通常为32或64)每经过一个处理它的路由器,它的值就减1,为0时,数据报就被丢弃,并发送ICMP报文通知源主机。
协议字段可以识别是哪个协议向IP传送数据。
首部检验和字段是根据IP首部计算的检验和码。它不对首部后面的数据进行计算。ICMP、IGMP、UDP、TCP在它们各自的首部中均含同时覆盖首部和数据的校验和码。
为计算一份数据报的IP首部检验和,首先把检验和字段置为0,然后对首部中每个16bit异或(或模2加,结果相同),结果取反后存在检验和字段中,当收到一份IP数据报后,同样对首部中每个16bit进行异或(或模2加,结果相同),此时,如果首部在传输过程中没有发生任何差错,那么接收方计算的结果应该全为1,如果不是全1,则检验和错误,IP应丢掉收到的数据报,但不生成差错报文,由上层去发现丢失的数据报并进行重传。不发送ICMP差错报文是由于IP本就是不可靠的传输协议,并且由于收到的IP数据报的首部有误,可能是源IP有问题,而向出问题的IP发送差错报文也没有意义。
ICMP、IGMP、UDP、TCP协议都使用相同的检验和算法。由于路由器经常只修改TTL字段(减1),因此当路由器转发一份报文时可以增加它的检验和,而不需要对整个IP首部进行重计算。但标准BSD实现在转发数据报时并不是采用这种增加的办法。
最后一个字段是选项,是数据报中的一个可变长的可选信息,可以是以下选项内容,这些内容很少使用,并非所有主机和路由器都支持这些选项,选项内容可以是:
1.安全和处理限制(用于军事领域)。
2.记录路径(让每个路由器都记下它的IP地址)。
3.时间戳(让每个路由器都记下它的IP地址和时间)。
4.宽松的源站选路(为数据报指定一系列必须经过的IP地址)。
5.严格的源站选路(与4相似,但要求只能经过指定的这些地址)。
选项字段一直是以32bit为界限,不够时插入0字节,这样可以保证IP首部长度是32bit的整数倍(这是首部长度字段要求的)。
对于IP路由,如果目的主机与源主机直接相连(如点对点链路)或都在同一共享网络上(如以太网、令牌环网等),那么IP数据报就直接送到目的主机上,否则,主机把数据报发送到与目的地址匹配的路由器上,由路由器转发该数据报。
当今的大多数多用户系统,包括几乎所有的UNIX系统,都能配置成一个路由器,我们可以为它指定主机和路由器都可以使用的简单路由算法。本质区别在于主机从不把数据报从一个接口转发到另一个接口,而路由器要转发数据报。
IP可以从TCP、UDP、ICMP、IGMP接收数据报(即在本地生成的数据报)并进行发送,或者从一个网络接口接收数据报并进行发送。IP层在内存中有一个路由表,收到一份数据报并进行发送时,都要搜索一次该表。当数据报来自某个网络接口时,IP协议首先检查目的IP是否为本机的IP地址之一或IP广播,如果是,数据报就被送到由IP首部协议字段所指定的协议模块进行处理,如果不是,若IP层被设置为路由器功能,那么对数据进行转发,否则丢弃数据。
路由表中包含:
1.目的IP地址。它既可以是一个完整的主机地址,也可以是一个网络地址,由该表中的标志字段来指定。主机地址有一个非0的主机号,以指定某一特定主机,而网络地址中的主机号为0,以指示网络中所有主机。
2.下一跳路由器的IP,或有直接连接的网络的IP地址。
3.标志。有一个标志指明目的IP是网络地址还是主机地址;有一个指明下一跳路由器是真正的下一跳路由器还是一个直接相连的网络。
4.为数据报的传输指定一个网络接口。
IP路由选择是逐跳进行的,IP并不知道到达任何目的地的完整路径(除了与主机直接相连的目的地址),所有IP路由选择只为数据报提供下一跳路由器的IP,它假定下一跳路由器更接近目的,且下一跳路由器与主机是直接相连的。
IP路由选择工作次序:
1.搜索路由表,寻找与目的地址匹配的条目,(网络号和主机号都要匹配),如找到,将该报文发送给它。
2.搜索路由表,寻找与目的地址网络号相匹配条目,并将报文发送给它。目的网络上所有主机都可通过这个表项来处置。
3.搜索路由表,寻找默认表项,将数据报发给它。
如以上步骤都失败,那么该数据报不能被传送,如果该数据报来自本机,则一般会向生成数据报的应用返回一个主机不可达或网络不可达的错误。
IP路由选择只需为一个网络指定路由器,而不用为每个主机都指定一个路由器,这样可以缩小路由表规模。
例子:
如上图,当bsdi主机上的IP从某个上层收到这份数据报后,搜索路由表,发现目的IP在一个直接相连的网络上(本网络上),于是就找到了路由表中匹配的网络地址项(假设bsdi的路由表中没有到sun主机的路由,而只有网络地址的路由)。然后数据报被送到以太网驱动程序,作为一个以太网数据帧被送到sun主机上。而链路层首部中的目的地址是48bit的sun主机以太网接口地址,以太网接口地址可通过ARP协议获得。
另一个例子:
bsdi有一份IP数据报要传到ftp.uu.net主机,它的IP是192.48.96.9,上图显示经过的前三个路由器。首先主机bsdi搜索自己的路由表,但没有找到与主机地址或网络地址匹配的表项,因此只能用默认表项,即将数据报传给下一站路由器(主机sun)。sun接受到的帧中,目的IP是最终信宿地址,而链路层地址是sun主机的以太网接口地址。
而当sun收到数据报后,它发现目的IP不是本机的任一地址,而sun已被设置成具有路由器的功能,因此它把数据报转发,搜索路由表后,发到下一站路由器netb,且数据报是通过点对点SLIP链路传送的。
netb收到数据报后,它执行与sun主机相同的步骤,把数据报送给下一站路由器gateway,主机netb用APR获得48bit的以太网地址,这个地址就是它发出的链路层数据帧头上的目的地址。
路由器gateway执行同样的操作。
上个例子中,所有主机和路由器都使用了默认路由。目的IP地址始终不发生变化(只有使用源路由选项时,目的IP才可能被修改),所有路由选择决策都基于这个IP地址。每个链路层都有不同的数据帧首部,且链路层的目的地址始终指的是下一站的链路层地址。以太网地址一般通过ARP协议获得。
现在所有主机都要求子网编址,IP地址从网络号+主机号变成网络号+子网号+主机号。原因是A类和B类地址为主机号分配了太多空间,分别能容纳224-2和216-2个主机(由于全0和全1的主机号无效,因此减2)。
在InterNIC获得某类IP网络号后,可由当地系统管理员决定是否建立子网,以及分配子网号和主机号。如现有一个B类网络地址140.252,可能会这么分:
上图是很多人采用的划分方法,这样点分十进制表示IP地址确定主机号时比较方便,但并不要求都这么分。
外部路由器隐藏了子网内部网络组织的细节,上例中B类地址的子网划分如下:
如上图,一台路由器提供了Internet的接入,路由器编号为Rn,n是子网号(这些子网属于同一个网路)。以太网用实线表示,点对点链路用虚线表示。
用一个包含30个子网的一个B类网络而非30个网络地址相比,可以缩小路由表的规模,上例中140.252被划分为若干子网的事实对于所有子网外的路由器都是透明的。为到达IP以140.252开始的主机,外部路由只需知道gateway路由器的地址即可,路由表中放一项即可。
子网对于子网内部的路由器是不透明的,子网内的路由器通过查表只能知道下一站路由器的地址。
主机在引导(即boot、启动)时的部分配置是指定主机IP地址。大多系统把IP地址放在一个磁盘文件中供引导时使用。除了IP地址,主机还须知道多少比特用于子网号和主机号,这是引导过程中通过子网掩码来确定的,掩码是一个32bit值,值为1的比特留给网络号和子网号,0留给主机号:
如上图,尽管IP地址一般以点分十进制表示,但子网掩码常用16进制值表示。
给定IP地址和子网掩码后,主机就可以确定IP数据报的目的是以下哪种:
1.本子网上的主机。
2.本网络中其它子网中的主机。
3.其它网络上的主机。
知道本机的IP可以知道:
1.它是否是A、B、C类地址。
2.从而得知网络号和子网号之间的分界。
3.又通过子网掩码得知子网号和主机号之间的分界。
上图中0表示所有比特位都是0,-1表示所有比特位都是1,netid、subnetid、hostid分别表示不为全0和全1的字段,子网号为空表示没有划分子网。上表的前两项是特殊的源地址,中间是特殊的环回地址,最后四项是广播地址。前两项网络号为0,只能在主机使用BOOTP(Bootstrap Protocol,引导程序协议)确定本机IP地址时作为初始化过程中的源地址出现。
一个子网的例子:
上图中,子网13中有两个分离的网络,一个以太网、一个点对点链路(硬件连接的SLIP链路,点对点链接一般在两端都需要IP地址)。将来可能有更多的主机和子网,为了不让主机跨越不同的网络需要使用不同的子网号,但上图解决方法是把子网号从8bit扩充为11bit,从而主机号从8bit减为了5bit,这叫变长子网,因为网络140.252中大多子网都用8bit子网掩码,而上图的140.252.13子网使用11bit子网掩码。
RFC 1009允许一个含有子网的网络使用多个子网掩码。但问题在于不是所有的路由选择协议在交换目的网络时也交换子网掩码。RIP(Routing Information Protocol,路由信息协议)不支持变长子网,RIP第二版和OSPF(Open Shortest Path First,开放式最短路径优先)支持变长子网。
ifconfig命令一般在引导时运行,以配置主机上的每个接口。
拨号接口可能会经常接通和挂断(如SLIP链路),每次线路接通和挂断时,SLIP软件必须用某种方法运行ifconfig命令更新接口信息。
查看所有接口信息的命令:
环回接口被认为是一个网络接口,它是一个A类地址,没有进行子网划分。
以太网没有采用尾部封装,而且可以进行广播,而SLIP链路是一个点对点链接。
SLIP接口(上图中的sl0)的标志LINK0表示允许发送CSLIP数据,其它选项有LINK1(如果从另一端收到一份压缩报文,就允许采用CSLIP发送数据)和LINK2(所有外出的ICMP报文都丢弃,一般不设置,但由于一些不当ping操作,不设置时可能会导致吞吐量降到0)。
另一台路由器的接口情况,ifconfig的-a选项是SunOS的功能,下图系统上没有此选项,因此我们必须多次执行ifconfig命令:
上图中显示,以太网接口we0有标志SIMPLEX,这个4.4BSD的标志表明接口不能收到本机传送的数据。这样设置后,如果接口发送一帧数据到广播地址,那么就会为本机拷贝一份数据送到环回地址。
netstat命令也提供系统上的接口信息,-i选项打印出接口信息,-n选项打印IP地址而非主机名:
此命令可打印接口的MTU、输入分组数(Ipkts)、输入错误数(Ierrs)、输出分组数(Opkts)、输出错误数(Oerrs)、冲突数(Collis,越高说明网络越饱和)、当前输出队列长度(Queue)。
IP协议有三个问题:
1.超过半数B类地址已被分配,快用尽。(目前全部IPv4地址都已经用完)
2.32bit的IP地址从增长的角度看一般是不够用的。(目前已用完)
3.当前路由结构没有层次结构,是平面型的结构,每个网络都要一个路由表项。随着网络数增长,路由表的规模会不断增长。无类别的域间路由选择CIDR(Classless Interdomain Routing)可解决它。
环回地址不一定是127.0.0.1,范围为以127开头的地址(127.0.0.1 - 127.255.255.254),但通常用127.0.0.1来表示。
子网号为16bit的A类地址与子网号为8bit的B类地址的子网掩码相同。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!