应用层 | HTTP,FTP | |
运输层 | TCP, UDP | 段(Segment) |
网络层 | IP, ICMP, IGMP | 数据报(Datagram) |
链路层 | 帧(Frame) | |
物理层 |
应用层关心的是应用程序的细节,而不是数据在网络中的传输活动;下面四层对应用程序一无所知,但它们要处理所有的通信细节。
周知端口号(Well-Known Ports) | 1-255 |
Unix系统占用端口 | 256-1023 |
临时可分配端口 | 1024-5000 |
为其他服务预留端口 | 5001- |
大多数TCP/IP分配的端口在1024-5000之间。
环回接口:127.0.0.1 or localhost,可简单理解为本机的ip地址。
注:IP输出函数的入口是和IP输入函数的出口都是网络层,下图是链路层的环回接口如何处理来自网络层的IP数据报。
注意点1:传给环回接口(127.0.0.1)的任何数据均作为IP输入(即从链路层传给网络层)
注意点2:传给广播和多播的数据复制一份传给环回接口(即广播和多播地址包含主机本身)
注意点3:任何传给该主机IP地址的数据均送到环回接口(比如该主机IP为172.18.156.139,则从网络层传到链路层的以该IP为目的地址的数据报,均送到环回接口再返回给网络层,所以一个传给环回接口的IP数据报不能在任何网络上出现)
最大传输单元MTU表示链路层数据帧所能传输的最大字节数。
如果IP数据报的长度比链路层的MTU还大,那么IP层就需要分片。
路径MTU:两台主机路径中的最小的MTU。
IP协议提供不可靠,无连接的数据报传送服务。
不可靠:不保证IP数据报成功到达目的地。
无连接:IP不维护后续数据报的状态信息(不一定按序发送和接收)。
IP首部一般为20个字节,除非包含选项字段。
版本:IPv4或IPv6
首部长度:首部的长度,以4 byte为单位,包含选项字段。该字段共4 bit,因此IP首部最长为60 Byte,且必须为4 Byte的倍数
服务类型:
总长度:整个IP数据报的长度,以byte为单位。该字段共16 bit,所以IP数据报最长为2^16 byte
标识:唯一标识主机发送的每一份数据报
TTL:Time-To-Live,数据报可以经过的最多路由数
协议:识别是哪个协议向IP协议传送数据,包括TCP,UDP,ICMP,IGMP……
首部检验和:根据IP首部计算的检验和码(将该字段置0,对首部中每16bit进行二进制反码求和,结果存在该字段;接收方收到后对首部中没16bit进行二进制反码求和,若结果全为全1,则正确)(注意是对IP首部进行检验,而不是IP首部+IP数据,而UDP的检验和是针对UDP首部+UDP数据)(但是为什么要反码?)
IP地址:32bit,记录格式一般为点分十进制(e.g. 192.168.1.1)
为什么要用反码求和而不是原码求和来检验首部和?
1)首先,我们要明确反码求和和原码求和的区别,反码求和溢出时,即最高位有进位,则将该进位加到最低位上;而原码求和则是丢弃该进位。
2)其次,明确Big Endian字节序和Little Endian字节序:
TCP/IP网络传输时,先传0-7bit,其次8-15bit,然后16-23bit,最后24-31bit(从小到大),这叫网络字节序,也叫Big Endian字节序。
Big Endian字节序:最高字节在地址最低位,最低字节在地址最高位
Little Endian字节序:反之
比如将 0x1234 存入 0x0000 开始的内存
Memery Big Endian Little Endian
0x0000 0x12 0x34
0x0001 0x34 0x12
3)那么,使用反码求和就可以不依赖系统是Big Endian字节序还是Little Endian字节序,而原码求和会受到字节序的影响。
4)最后,举个例子就明白了。
原码:
10000000 00000000
+10000010 00000000
=00000010 00000000
原码,使用另一种字节序:
00000000 10000000
+00000000 10000010
=00000001 00000010
反码:
01111111 11111111
+01111101 11111111
=11111101 11111111
反码,使用另一种字节序:
11111111 01111111
+11111111 01111101
=11111111 11111101
可以看到,反码求和,改变了字节序,结果相同,只是字节顺序相应地也交换了;而原码的结果就不同了。
IP从TCP,UDP,ICMP和IGMP接收数据报(即本地生成的数据)并进行发送,或者从一个网络接口接收数据进行转发或接收。
1)当数据来自TCP,UDP,ICMP和IGMP(从上传递下来的):
传递给链路层
2)当数据报来自网络接口(从下传递上来的):
(1)IP首先判断IP地址是否为本地地址或者广播地址,如果是就送到首部协议段所指定的协议模块进行处理(继续向上传递)
(2)如果不满足这些地址,且IP层设置为了路由功能,那么就对数据报进行转发,否则数据报被丢弃
那么,什么叫IP的路由功能呢?有了路由功能怎么对数据报进行转发呢?
当收到一个IP数据报的时候,IP并不知道该数据报达到最终目的的完整路径,所有的IP路由选择只为数据报提供下一站路由器的IP地址,IP的路由选择功能为:
1)搜索路由表,寻找目的IP地址(网络号+主机号),找到则发给该行记录的下一个路由器
2)若1)失败,则继续搜索路由表,寻找目的IP地址的所在网络号,找到则发给该行记录的下一个路由器
3)若2)失败,则继续搜索路由表,寻找叫做“默认”的那行记录,找到则发给该行记录的下一个路由器
4)若3)失败,则该数据报就不能被传送
IP地址=网络号+子网号+主机号
子网掩码即与IP地址对应的网络号和子网号为1,主机号为0的32个bit
子网的划分缩减了路由表的规模:
为了到达IP地址为140.252.*.*的主机,路由表现在只需记录到达子网络140.252的下一跳,而不需要记录该子网下的所有主机的下一跳。
链路层的以太网地址是48位(如:20-6A-8A-4B-E9-2F),而网络层的IP地址是32位(如:172.18.156.36)。
而ARP和RARP就是为IP地址与硬件地址之间提供动态转换。
当用户输入ftp://www.abc.com(或http://www.baidu.com)的时候,发生的事情如下:
具有本地磁盘的系统引导时,一般是从磁盘上的配置文件中读取IP地址。但无盘机则需要利用RARP来获得它自己的IP地址。
无盘机可以读取自己的硬件地址,然后广播一份RARP请求(含其硬件地址)给该网内的其他主机,请求某个主机响应该无盘系统的IP地址(在RARP应答中)。
ICMP时间戳请求允许系统向另一个系统查询当前的时间。
请求端填写发起时间戳,然后发送请求报文,应答端收到报文的同时填写接收时间戳和传送时间戳,然后发送应答报文。
其中发起时间戳是指请求端的发送时间,而传送时间戳是指应答端的发送时间。一般设接收时间戳和传送时间戳为相同的值。
假如请求端收到的应答报文如下:
其中,发起时间比接收时间早6ms,而rtt=2ms,所以请求端的时间比应答端的时间早7ms。
为什么,见下图自己理解。
Ping程序发送ICMP回显报文给目标主机,并等待返回ICMP回显应答。
Ping程序发送的是ICMP报文,是对两个TCP/IP系统连通性进行测试的基本工具。
Traceroute程序可以让我们看到IP数据报从本主机到另一台主机所经过的路由的地址。
Traceroute程序使用ICMP报文和IP数据报中的TTL字段来实现:
(1)发送端发送一个TTL为1的UDP数据报,收到该数据报的路由器将TTL减一,发现TTL为0,于是丢弃该数据报并发回一份ICMP超时报文;
(2)发送端接收到ICMP超时报文的时候就可以提取里面的IP地址,由此得知第一跳的IP,然后发送一个TTL为2的UDP数据报,接受到的路由器将TTL减一,如果TTL不为0则继续转发,如果为0则丢弃该数据报并发回一份ICMP超时报文;
(3)以此类推,直到目的主机接收到该UDP数据报,发现自己是目的主机,则丢弃该数据报并发回一份ICMP端口不可达的报文。
(4)发送端根据收到的是ICMP超时报文还是ICMP端口不可达报文来确定是否成功达到目的主机。
U 该路由可用
G 该路由是一个网关,如果没有此标志,说明下一跳就是目的地
H 该路由的目的地址为主机地址,无此标志表示目的地址为网络地址(网络地址的主机号全为0)
D 该路由由重定向报文创建
M 该路由被重定向报文修改
如上图,假如目的地址是140.252.13.33。
查找路由表,发现第一第二行是主机地址,均不完全匹配;第三行是default,暂时跳过;第四行的网络部分与该IP地址的网络部分相同,所以使用第四行的数据,将IP数据报经接口emd0发给140.252.13.34。
疑问:虽然方法正确,但是IP数据报并没有发送给正确的目的地(140.252.13.33),这只是路由表的问题吗?
假如路由表中没有找到合适的行(路由表中也没有default项),那么路由会如何处理呢?当然是丢弃该IP数据报,然后……
(1)如果该IP数据报是本机产生的,那么就给发送该数据报的应用程序返回一个差错
(2)如果该IP数据报不是本机产生的,那么就给原始发送端发送一份ICMP主机不可达的差错报文
ICMP重定向报文是ICMP控制报文中的一种。
在特定的情况下,当路由器检测到一台主机使用非优化路由的时候,它会向主机发送一个ICMP重定向报文,请求主机改变路由表。
同时,负责任的路由器也会把初始数据报向它的目的地转发。
什么情况下路由器会发送ICMP重定向报文呢?
如图,当路由器发现源IP地址与下一跳属于同一网段时。
静态选路:配置接口时,以默认方式生成路由表项(路由表项就是表的每一行数据)或使用route命令来手工添加表项,或通过ICMP重定向生成表项
动态选路:
路由表中有一个常驻内存的程序,叫路由守护程序(routing daemon)。该程序与其相邻的路由表进行通信,根据得到的信息更新路由表。
工作过程
(1)初始化
在启动一个路由守护程序时,它先判断启动了哪些接口,并在每个接口上发送一个请求报文,要求其他路由器发送完整路由表
(2)接收到请求
例如,有4个路由ABCD,B和AC相连,不与D相连。某时,A通知B,C和D与B的距离为1。B收到后,更新了与C的距离为1,但是它与D不相连,于是更新了与D的距离为16
(3)接收到响应
更新路由表
(4)定期选路更新。每过30秒,所有或部分路由器会将其完整路由表发送给相邻路由器
(5)触发更新
每当一条路由的距离发生变化时,就对它进行更新。不需要发送完整路由表,而只需要发送那些发生变化的表项。每条路由都有与之相关的定时器。如果发现一条路由在3分钟内未更新,就将该路由的距离设置成无穷大(16),并标注为删除。这意味着已经在6个30秒更新时间里没收到通告该路由的路由器的更新了。再过60秒,将从本地路由表中删除该路由,以保证该路由的失效已被传播开
RIP采用距离向量,而OSPF采用链路状态信息来更新路由表(RIP中,路由表交换的信息是路由与路由的距离)。
OSPF比RIP收敛快(一旦有路由器崩溃,RIP中消息传得太慢),因此规模较小的网络可以采用RIP,规模较大应采用OSPF。
OSPF通过路由器之间通告网络接口的状态来建立链路状态数据库,生成最短路径树,每个OSPF路由器使用这些最短路径构造路由表。
例如,A连B和D,B连C和D。开始,AB通信,B告诉A,BC=1,BD=1。那么A就可以计算得出,AB=1,AC=2,AD=2。然后AD通信,D告诉A,BD=1。然后A权衡,发现通过D到B则AB=2,通过B到B则AB=1,则取AB=1;其次,通过B到D,AD=2,通过D到D,AD=1,则取AD=1。最终A的路由表为,AB=1,AD=1,AC=2。
通过这里例子可以可以看到,RIP只保存到达目标地址的下一跳路由的信息;而OSPF保存了局域网内所有路由的信息。
含义:Domain Name System,域名系统
功能:提供域名和IP地址相互映射
为了避免记住纯数字组成的IP地址,人们发明了域名。为此,域名与IP地址之间要有映射关系。
刚开始,每台主机有一个HOSTS文件(位置:C:\Windows\System32\drivers\etc\hosts),里面存放着世界上所有域名和IP的映射关系,这样域名解析的任务每台计算机都可以独立完成。但是这样HOSTS文件过于分散,不易统一管理;而且IP越来越多,这个文件越来越大。
那么最简单的,如果世界上有一台服务器,存储着世界上所有域名和IP的映射关系,即整个世界只有一份HOSTS文件,那么确实易于管理,所有计算机上网的时候就可以去访问它得到正确的IP,但是这样这台服务器会不堪重负。
所以,DNS应运而生。DNS采用的是分布式的解析方案。见下图。
至今为止,这个世界上有13台根服务器。根服务器的任务就是将域名解析的任务分配给顶级域的服务器。顶级域的服务器也可以像根服务器那样将解析权分配给下属服务器。
例如根服务器会将所有com域名的解析任务全部交给负责com的服务器,负责com的服务器会将所有cnblogs.com域名的解析任务全部交给负责cnblogs.com的服务器。
常见的顶级域名有:
com | 商业组织 |
edu | 教育机构 |
gov | 美国政府部门 |
net | 网络 |
org | 其他组织 |
推荐阅读:浅谈DNS体系结构:DNS系列之一
我们在浏览器上输入i.cnblogs.com之后,我们这台主机会向DNS服务器发送一条DNS查询报文以查询该域名对应的IP。
(注意,该报文是UDP报文,不需要与DNS服务器建立TCP连接;我们这台主机本来就知道DNS服务器的IP地址,要么是写好的静态IP,要么是路由器动态分配的IP,不是域名,所以DNS查询这个过程也不需要去解析域名,否则无限循环了……)
DNS服务器若有关该域名的记录,则发送IP回我们的主机,结束。
DNS服务器若不知道,则它向根服务器发送关于该域名的请求。
(注意,每台DNS服务器都必须知道根服务器的IP,这是作为一台DNS服务器的素养)
根服务器收到后发现,这是com结尾的,于是返回负责com域名解析的服务器的IP给DNS服务器。
DNS服务器收到后,就把关于该域名的请求发给负责com域名解析的服务器。
负责com域名解析的服务器收到后发现,这是cnblogs.com结尾的,以cnblogs.com结尾的域名的解析权已经委派给XX服务器了,于是返回负责cnblogs.com域名解析的服务器的IP给DNS服务器。
DNS服务器收到后,就把关于该域名的请求发给负责cnblogs.com域名解析的服务器。
负责cnblogs.com域名解析的服务器收到后发现,这是我负责的域名,查询一下资源记录,OK找到了,于是发回i.cnblgos.com的对应IP给DNS服务器。
DNS服务器千辛万苦终于得到该IP,自己先缓存一下,然后发回给我们的主机,结束。
某个区域的资源记录通过手动或自动方式更新到主 DNS服务器上,辅 DNS 服务是为了防止主服务器无法访问或宕机。辅 DNS服务器定期与主 DNS 服务器通讯,确保它的信息保持最新。如果不是最新信息,辅 DNS服务器就会从主服务器获取最新信息的副本,称为区域复制。辅 DNS 服务器一般是3个小时查询一次是否主 DNS 服务器更新。
为了减少Internet上DNS的通信量,所有的DNS服务器均使用高速缓存。
Windows上清空DNS缓存的方法:命令行输入ipconfig/flushdns
A | 将域名转为IP |
PTR | 将IP转为域名 |
CNAME | 一个IP对应多个域名 |
NS | 该区域的DNS服务器 |
SOA | 该区域的主DNS服务器 |
MX | 邮件交换记录 |
区域传送时DNS使用TCP,大多数情况(域名解析)使用UDP。
为什么区域传送使用TCP?
为什么域名解析使用UDP?
假设客户端和服务器都没有DNS缓存,且Rlogin服务器收到IP数据报时需要进行主机名检查(利用IP报文中的IP地址向DNS服务器询问其对应域名,再利用该域名向DNS服务器询问其对应IP,再检查该IP是否跟IP报文中的源IP一致,好麻烦不知道为什么)。
(1)Rlogin客户端中没有关于Rlogin服务器的域名解析,所以只能向根名字服务器查询Rlogin服务器的IP地址(这是一条A记录的查询)
(2)根名字服务器当然不知道怎么解析,只告诉Rlogin客户端谁(图中的服务器的名字服务器)在负责这个域名的解析(这是一条NS记录)
(3)Rlogin客户端收到后知道是服务器的名字服务器在负责,所以向服务器的名字服务器查询Rlogin服务器的IP地址(这是一条A记录的查询)
(4)服务器的名字服务器返回的报文中包含了Rlogin服务器的IP地址(这是一条A记录的应答)
(5)于是Rlogin客户端知道了Rlogin服务器的IP地址,于是与其建立TCP连接
(6)此时我们情景设定Rlogin服务器需要进行主机名检查,于是利用TCP连接中得到的IP地址向根名字服务器(跟(1)中的不一定是同一个)查询Rlogin客户端的域名(这是一条PTR记录的查询)
(7)根名字服务器当然不知道怎么解析,只告诉Rlogin服务器谁(图中的客户的名字服务器)在负责这个域名的逆解析(这是一条NS记录)
(8)Rlogin服务器收到后知道是客户的名字服务器在负责,所以向客户的名字服务器查询Rlogin客户端的域名(这是一条PTR记录的查询)
(9)客户的名字服务器返回的报文中包含了Rlogin客户端的域名(这是一条PTR记录的应答)
(10)Rlogin服务器收到后知道了Rlogin客户端的域名后,向客户的名字服务器查询Rlogin客户端的IP地址(这是一条A记录的查询)
(11)客户的名字服务器返回的报文中包含了Rlogin客户端的IP地址(这是一条A记录的应答)
最后Rlogin服务器将得到的IP地址和TCP连接中的IP地址进行比对(为什么要主机名检查这么麻烦……)