精华内容
下载资源
问答
  • 计算机三级网络技术考过指南

    万次阅读 多人点赞 2018-03-10 19:18:36
    计算机三级网络技术考过指南 原文链接:计算机三级网络技术考过指南 题库下载链接(50积分是CSDN上调的,不是我上传时设置的。更新版本请大家自行搜索):计算机三级网络技术无纸化考试模拟软件(2018.3) 用...

    计算机三级网络技术考过指南


    原文链接:计算机三级网络技术考过指南

    题库下载链接(50积分是CSDN上调的,不是我上传时设置的。更新版本请大家自行搜索):计算机三级网络技术无纸化考试模拟软件(2018.3)

    用Markdown重写后的带完整标签的版本:计算机三级网络技术考过指南(带完整标签版)


    目录

    计算机三级网络技术考过指南

    前言(必读)

    1.基础准备

    1.1 题库

    1.2 二进制转换

    1.3 基础概念

    1.4 备考建议

    2.选择题(40 道 40 分)

    2.1 第一类选择题

    2.2 第二类选择题

    2.3 第三类选择题

    3.大题(前四道每道10分,最后一道20分)

    3.1 第一道 填地址表

    3.2 第二道 配置路由器

    3.3 第三道 DHCP 报文

    3.4 第四道 sniffer 数据包

    3.5 最后一道

    总结:得分策略


    前言(必读)


    本文档总大小 5MB 左右,请注意流量 
    若手机端浏览不便,请尝试使用电脑浏览器

    这份指南写于我备考三级一周后,因为做了几套题之后感觉这个考试的知识点和题型很固定,而将这些知识点和做法概括总结出来可以帮助以后考试的同学。

    对于没有相应基础的绝大多数同学,如果想考过三级网络技术,首先要克服见到陌生复杂题目的恐惧感。话说回来,其实这些题没有哪一道是真正需要动脑进行复杂思考的,只是知识点没见过,做题的方法不清楚,一旦知道了就能写对。这个考试没有什么含金量,一周的练习基本上足够了。

    我们专业去年上了计算机网络这门课,但跟这个考试的关系不大,只有少量的考点学过。所以我对题目的解析是很业余的,但这也是个好处,正是因为不专业写的就比较直白,适合没有基础的同学参考。

    另外,需要强调一下,本文档以应试为目的指在帮助你通过考试,而非掌握计算机网络技术。

    如果发现有错误或者有其他建议请与我联系,多谢。

    我的邮箱:increasesong@foxmail.com

    请勿修改这份文档 
    欢迎把笔记链接分享给有需要的同学

    后增:为什么考三级? 
    既然二级都过了,再考个三级呗,有的学校可能还有实践学分。别人二级office的很多,你三级看上去就显得厉害一点。

    【重要更新】 
    自2018年3月份全国计算机等级考试(第51次)起,取消了三级获证的前置条件。直接报名考三级就可以了,不再需要对应的二级科目通过。

    为什么三级选网络技术这科? 
    因为我考的时候,查了查发现考这个的最多,考的人越多的科目考试题就可能越标准规范,我对其他的科目也没有特别有兴趣的,所以就考这个了。所以我也只能写网络技术,所以你们选网络技术备考也就最方便。

    要不要考四级? 
    计算机等级考试基本是给非计算机专业设置的考试,所以本来就没什么含金量,我没有考。还想考计算机方面的证,可以去考软考[计算机技术与软件专业技术资格(水平)考试]。 
    听说计算机等级考试四级比三级还简单,也是买题做题就行了。


    1.基础准备

    1.1 题库

    买一本三级网络技术题库或者是题库软件(20 元左右),不需要买更多,总之有成套的题可以做就行。真题目前大概有二十套左右。

    1.2 二进制转换

    应该学过

    网络技术用到的一般是八位二进制数。也就是 0 ~ 255,即 0000 0000 ~ 1111 1111(每四位空一格便于观察)

    我做题前在草稿纸上先这样画


    这样,比如说我看见 1001 1000 这个数,就知道这是 128+16+8 对应的数。

    反过来,十进制转换二进制也可以利用这个简图。还有一些规律,自己做题中摸索吧,你可能会找到更好的方法。

    下面几组记忆一下,做题时会比较方便(不要畏难,做题见多了就记住了)

    二进制十进制
    1000 0000128
    1100 0000192
    1110 0000224
    1111 0000240
    1111 1111255

    1.3 基础概念

    如果是学过计算机网络相关知识的同学可以不看,下面是非专业的不标准的可能还有错的描述,仅仅是为了完全没有基础的同学有个粗略了解。

    计算机网络是一些电脑相互链接组成的,这些电脑叫做主机,可能相距很远,也可能是一间屋子里的。

    就像正常情况下两个人要用同一种语言交流一样。主机之间的联系也要按照相同的标准才行,这些标准叫做协议。因为主机之间的联系是一件复杂的事。所以有多种协议解决不同方面的问题,比如 TCP、BGP、DHCP 等等。

    相距太远的主机之间不能直接联系,就需要一些设备,比如路由器、交换机等等,你只知道他们都是为了主机联系的中间转发设备就行。

    还需要地址,因为没有地址就不知道主机在哪,这个标识主机的就是 IP 地址。 
    IP 地址是类似这样的:10000000.1110000.01000000.10110001,一共 32 位,为了人看起来方便就写成 128.224.64.177 这种点分十进制的形式。

    还有一种叫做 MAC 地址,是标识硬件设备的地址。

    主机还可以广播给整个网络,广播地址是 IP地址 32 位全置 1 的地址,即 255.255.255.255。

    当你访问一个网站,你的电脑先将网址发送给 DNS 服务器(域名解析服务器),这个服务器能将你写的网址域名变成 IP 地址,这样你的电脑就知道想要访问的网页放在哪了。

    上面这些并不能让你真正理解计算机网络(其实我也不是很清楚),主要是让你在见到陌生名词的时候别害怕,有些名词不理解也不会影响做题。

    1.4 备考建议

    这就是个人的方法了,也不一定适合你。

    【1】首先对着一套三级题和答案看一遍,每道题都看答案解析是怎么说的。看答案不必弄懂(当然你要真的全弄懂也很厉害),知道怎么选出来就行,不明白跳过也行。同时也找找看看我笔记里写没写这道题的知识点。

    这一遍是比较简略的,对题目有个简单的印象就够了。但这遍也是比较困难的,因为几乎都是陌生的东西。

    【2】接下来,同时做两三套试题甚至更多套。按着笔记里的知识点做,看到哪个知识点就到这些套题里找,对照着做题来掌握这个知识点。如果笔记里没有提到或者没写详细的就看答案怎么说,实在不明白的还可以跳过。

    这个阶段是需要比较认真的看了,我这个阶段是在写笔记中度过的。经过这个阶段你就能明白哪些知识点考察比较固定,一些题的固定做法是什么,对考试有比较完全的认识了。

    【3】接下来,就把剩下的套题都做了,反正一共就二十套左右。怎么做都行,按套或者按题型什么的自己安排,反正做一遍。如果没时间了,至少把选择题做一遍。

    这一遍就是完善熟练的阶段,还可能有一些我笔记里没写的知识点你也会了。

    【补充】有的同学还是感觉难,那就先把第一道大题和最后一道大题的两个填表都仔细弄会了。这两个表就 20 分到手了。接下来学习可能会感觉踏实一点。


    2.选择题(40 道 40 分)

    根据做题方法不同划为三类

    • 第一类:几乎每套题都考,掌握简单做法即可选出正确答案
    • 第二类:每套题里有 5 道左右,看上去非常复杂的大段配置代码
    • 第三类:从四个选项里选出一项正确或错误的,其中部分知识点是常考的,比较零散

    2.1 第一类选择题

    2.1.1 问传输速度

    OC-3 对应 155.52 Mbps 
    OC-12 对应 622.08 Mbps 
    (显然,这是一道送分题)

    2.1.2 求交换机带宽

    通常是求总带宽 
    例:某交换机有 12 个 10/100 Mbps 电端口和 2 个 1000 Mbps 光端口,所有端口都在全双工状态下,那么总带宽为( ) 
    解:忽略 10/100 中的 10,当成 100 Mbps 就好。12 * 100 + 2 * 1000 = 3200,又因为全双工所以乘以 2 得 6400 Mbps ,即 6.4 Gbps

    有时候求上联端口带宽 
    例:某交换机有 16个100/1000 Mbps 全双工下联端口,那么上联端口带宽至少为( ) 
    解:16 * 1000 * 2 = 32000 Mbps = 32 Gbps,上联一般是下联的 1/20 ,所以至少为 32 除以 20 得 1.6 Gbps

    2.1.3 系统可用性与停机时间

    可用性停机时间
    99.9%≤8.8小时
    99.99%≤53分钟
    99.999%≤5分钟

    也是送分题,但要记准确。比如 53 分钟,有时候会问 55 分钟的情况,要是记成 50 或者大约 1 小时就没法做了。

    2.1.4 写地址块的子网掩码

    例:IP 地址块 59.67.159.125/11 的子网掩码可写为( ) 
    解:不用看 IP 地址,只看 /11 就够了。 
    11 代表子网掩码的前 11 位都是 1 ,所以可以写出子网掩码 11111111.11100000.00000000.00000000 转换为十进制即是 255.224.0.0 
    做题熟练后其实不用写上面那堆 1 和 0 就能选出正确答案。

    2.1.5 网络地址转换 NAT


    会给你一个这样的图,问你 ① ② 是什么 
    只需要知道②和紧挨着它的 S 数字相同,所以②应该是 202.0.1.1,5001 ;同理,①是 10.0.0.1,3342。 
    还有时候会问某个小方框里的 S,D 分别是什么,看上面的图你会发现,上面两个方框和下面两个方框里的数字是对称的,做题时对称一下就写出答案了。

    2.1.6 IP 地址块聚合

    第一种:问聚合后的地址块 
    下面演示三个地址的聚合 

    步骤为:转成二进制;对齐找前多少位是相同的;转回十进制写答案。 
    这样就得出聚合后的地址为:192.67.159.192/26 
    Tips:转换二进制时,因为前三段十进制本来就一样,所以可以只转换最后一段; 
    不要一个一个数有多少位相同的,因为前三段相同就知道有 3 * 8 = 24 位,再加上 2 就是 26。

    第二种:问聚合后可用 IP 数 
    下面两种情况的做法由网友 Yes 补充,十分感谢
    ,之前我写的不当方法已删除。

    【第一种情况】如未来教育上机考试第一套试题第10题: 
    “ IP 地址块 202.113.79.128/27、202.113.79.160/27 和 202.113.79.192/27 经过聚合后可用的地址数为___”

    因为格式都是 xxx.xxx.xxx.xxx/27,本题中“/”后边的数字都是相同的。 
    所以遇到这种题,先把前两个 IP 聚合求出可用地址数,然后单独算出第三个 IP 地址可用地址数,两个地址数相加即正确答案。

    【第二种情况】如未来教育上机考试第三套试题第10题: 
    “ IP 地址块 202.113.79.0/27、202.113.79.32/27、202.113.79.64/26 经过聚合后可用的地址数为___”

    本题中“/”后边的数字前两个是相同的,第三个与前两个不同。 
    所以遇到这种题,直接将三个 IP 聚合得到地址块,然后求出三个 IP 的可用地址数。

    2.1.7 路由表距离更新

    例:R1,R2 是一个系统中采用RIP路由协议的两个相邻路由器,R1 的路由表如(a)所示, 
    R1 收到 R2 发送的报文(b)后,R1 更新后的距离值从上到下依次是( ) 

    解:做法如下 
    步骤为:b距离+1;
    与a距离比较;更新为距离最小的。则更新后的距离值从上到下依次是 0、4、4、3、2

    还经常这样考——给出更新后距离值和(a)中的距离,求(b)报文距离的可能值。 
    规则不变,上面的做法反过去求就行。

    2.1.8 IPv6 地址简化表示

    例:某地址 FF23:0:0:0:0510:0:0:9C5B, 
    可以简化为 FF23::0510:0:0:9C5B,双冒号替代连续出现的 0 位段, 
    不能简化为 FF23::0510::9C5B,因为双冒号只能使用一次, 
    可以简化为 FF23::510:0:0:9C5B,因为 0510 就是 510 , 
    不能简化为 FF23::051:0:0:9C5B,因为 0510 不是 51。

    例:下列 IPv6 地址表示中错误的是( ) 
    A) ::10F:BC:0:0:03DA 
    B) FE::0:45:03/48 
    C) FE31:0:BC:3E:0:050D:BC::03DA 
    D) FF34:42:BC::3E:50F:21:03D 
    解:IPv6 地址是 128 位划分为 8 段的地址,而 C 项不算双冒号那段已经有了 8 段,双冒号又至少压缩一个 0 位段,所以超了 8 段,是错误的。 
    B 中的 /48 做题时可以忽略,写不写没关系。做这种题先看最长的那项有没有超过 8 段。

    2.1.9 数据包

    例:下图是 A 发送的数据包通过路由器转发到 B 的过程示意图,求数据包 3 中的目的IP地址目的MAC地址 

    解:无论哪个数据包,目的 IP 地址就是 B 的 IP 地址,所以数据包 3 的目的 IP 为 129.42.56.216; 
    而目的 MAC 地址就是下一个路由器的 MAC 地址,数据包 3 的下一个路由器是 R3,所以数据包 3 的目的 MAC 地址是 00d0.63c3.3c41。

    2.1.10 三种备份

    备份速度从快到慢:增量备份、差异备份、完全备份(备份越详细越慢) 
    恢复速度从快到慢:完全备份、差异备份、增量备份(和上面顺序相反,也好理解,备份时详细的恢复快) 
    空间占用从多到少:完全备份、差异备份、增量备份(备份越详细占用空间越多) 
    题目通常问你其中某一种的顺序。

    2.2 第二类选择题

    这部分将进一步体现本指南的优越性 

    我们先来看一道“第二类选择题”的四个选项,不需要看题。

    -从这开始 


    -到这结束 
    看起来异常复杂,但这是在我完全不懂知识点的情况下就能选对的题。 
    下面要讲的是技巧方法,不是知识点,适用于这类题 
    首先,你需要来回观察这四个选项,找出他们的不同点。可能是两句颠倒的代码,可能是一个单词一个数,也可能是其他的。 

    这是我把他们不同的地方做了荧光标记 
    首先一眼看上去,C 项的大段数字位置和其他三项不一样,所以排除 C; 
    然后,看蓝色的数字,只有 A 项和其他三项不一样,所以排除 A; 
    最后,看绿色的地方,只有 B 项少了一句,所以排除 B; 
    选 D。

    悟性比较高的同学肯定已经明白了,为了大家更好的体会,再换一道题演示: 
    不先写选项了,直接展示标记后的 

    方法一样,找出不同点,然后“少数服从多数”,最后选 C。

    下面一道题自己练习一下 

    答案是C。

    说出来你可能不信,这种方法可以解决80%以上的“第二类选择题”, 
    有的题可能没办法排除掉三个选项,这时候就要结合一下题目内容推断来做或者蒙。

    2.3 第三类选择题

    下面列举的是高频考点,需要记忆,但不要死记。一开始可能感觉很陌生很难,做题碰见得多了就熟悉了能迅速选出答案。

    2.3.1 弹性分组环 RPR

    • 每一个节点都执行SRP公平算法
    • 与 FDDI 一样使用双环结构
    • 传统的 FDDI 环,当源结点向目的节点成功发送一个数据帧之后,这个数据帧由源结点从环中回收
    • 而 RPR 环,当源结点向目的节点成功发送一个数据帧之后,这个数据帧由目的结点从环中回收
    • RPR 采用自愈环设计思路,能在 50ms 时间内隔离故障结点和光纤段
    • 两个 RPR 结点间的裸光纤最大长度可达 100公里
    • RPR 的外环(顺时针)和内环(逆时针)都可以用于传输分组和控制分组

    2.3.2 无线接入技术

    • 主要有 WLAN、WiMAX、WiFi、WMAN 和 Ad hoc ( WiFi 肯定知道,记住无线技术一般是W开头的,但有个特殊的A开头)
    • APON 不是无限传输技术,这个经常是迷惑项

    2.3.3 广域网 QoS

    考的时候通常只写英文缩写,下面写上中文名是为了方便你记忆(其他的地方也应该养成粗略推测英文缩写的习惯)

    • 主要的技术有 资源预留(RSVP)、区分服务(DiffServ)、多协议标记交换(MPLS

    2.3.4 接入技术特征

    • ASDL 使用一对铜双绞线,具有非对称技术特性,上行速率 64 kbps~640 kbps,下行速率 500 kbps~7 Mbps
    • 采用 ADSL 技术可以通过 PSTN 接入 Internet
    • Cable Modom(电缆调制解调器)利用频分复用的方法将信道分为上行信道和下行信道,把用户计算机与有线电视同轴电缆连接起来
    • 光纤传输距离可达 100km 以上(这个知道光纤很远就行了)

    2.3.5 服务器技术

    • 热插拔功能允许用户在不切断电源的情况下更换硬盘、板卡等(不能更换主板卡)
    • 集群技术中,如果一台主机出现故障,不会影响正常服务,但会影响系统性能
    • 磁盘性能表现在储存容量和 I/O 速度(I/O=input/output 即输入/输出,学过计算机应该知道)
    • 服务器总体性能取决于 CPU 数量、CPU 主频、系统内存、网络速度

    2.3.6 综合布线

    • 双绞线可以避免电磁干扰
    • 嵌入式插座用来连接双绞线
    • 多介质插座用来连接铜缆和光纤,满足用户“光纤到桌面”的需求
    • 建筑群子系统可以是多种布线方式的任意组合,地下管道布线是最理想的方式
    • STP 比 UTP 贵、复杂、抗干扰能力强、辐射小
    • 水平布线子系统电缆长度在 90 m 以内
    • 干线线缆铺设经常采用点对点结合和分支结合两种方式

    2.3.7 BGP 协议

    • BGP 是边界网关协议,而不是内部网关协议(所以遇到问某两个自治系统之间使用什么协议,就选 BGP)
    • BGP 交换路由信息的节点数不小于自治系统数
    • 一个 BGP 发言人使用 TCP(不是UDP)与其他自治系统的 BGP 发言人交换信息
    • BGP 采用路由向量协议,而 RIP 采用距离向量协议
    • BGP 发言人通过 update 而不是 noticfication 分组通知相邻系统
    • open 分组用来与相邻的另一个 BGP 发言人建立关系,两个 BGP 发言人需要周期性地交换 keepalive 分组来确认双方的相邻关系

    2.3.8 RIP 协议

    • RIP 是内部网关协议中使用最广泛的一种协议,它是一种分布式、基于距离向量的路由选择协议,要求路由器周期性地向外发送路由刷新报文
    • 路由刷新报文主要内容是由若干个(V,D)组成的表。V 标识该路由器可以到达的目标网络(或目的主机);D 指出该路由器到达目标网络(或目标主机)的距离。距离D对应该路由器上的跳数。其他路由器在接收到某个路由器的(V,D)报文后,按照最短路径原则对各自的路由表进行刷新
    • 使用 RIP v1 路由协议在配置网络地址时无须给定子网掩码

    2.3.9 OSPF 协议

    • OSPF 是内部网关协议的一种,每个区域有一个 32 位的标识符,区域内路由器不超过 200 个
    • 区域内每个路由器包含本区域的完整网络拓扑,而不是全网的情况(拓扑的意思是链接形式和位置关系之类的)
    • 链路状态“度量”主要指费用、距离、延时、带宽等
    • OSPF 采用洪泛法交换链路状态信息

    2.3.10 集线器

    • 工作在物理层,连接到一个集线器的所有结点共享一个冲突域
    • 集线器不是基于 MAC 地址完成数据转发,而是用广播的方法
    • 在链路中串接一个集线器可以监听数据包
    • 每次只有一个结点能够发送数据,而其他的结点都处于接收数据的状态。这些结点执行CSMA/CD介质访问控制方法

    2.3.11 交换机

    • 是一种工作在数据链路层的网络设备,基本功能是维护一个表示 MAC 地址和交换机端口对应关系的交换表
    • 在源端口与目的端口间建立虚链接
    • 具有三种交换模式:1.快速转发直通式,接收到前 14 个字节就转发数据;2.碎片丢弃式,缓存前 64 个字节;3.储存转发式,转发之前读取整个帧
    • 三层交换机是具有部分路由器功能的交换机,用于加快大型局域网内部的数据交换

    2.3.12 路由器

    • 丢包率是衡量路由器超负荷工作时的性能指标之一
    • 背板能力决定路由器吞吐量
    • 传统路由器一般采用共享背板的结构,高性能路由器一般采用交换式的结构
    • 突发处理能力不是以最小帧间隔值来衡量的
    • 语音视频业务对延时抖动要求较高
    • 高端路由器应达到:无故障连续工作时间大于 10 万小时;故障恢复时间小于 30 分钟;切换时间小于 50 毫秒

    2.3.13 IEEE 802.11

    • IEEE 802.11 最初定义的三个物理层包括了两个扩频技术和一个红外传播规范,无线频道定义在 2.4GHz ISM频段,传输速度 1~2 Mbps
    • 802.11b 最大容量 33 Mbps,将传输速率提高到 11 Mbps802.11a802.11g 将传输速率提高到 54 Mbps
    • IEEE 802.11d 是当前最流行的 STP(生成树协议)标准
    • IEEE 802.11b 标准使用的是开放的 2.4GHZ 频段,无须申请就可以直接使用

    2.3.14 蓝牙

    • 同步信道速率 64 kbps,跳频速率为 1600 次/s
    • 工作在 2.402 ~ 2.480 GHz 的 ISM 频段
    • 非对称的异步信道速率为 723.2 kbps / 57.6 kbps
    • 对称的异步信道速率为 433.9 kbps
    • 发射功率为100mw时,最大传输距离为100米

    2.3.15 Serv-U FTP 服务器

    • 使用动态 IP 地址时,服务器 IP 地址应配置为空,而不是 0.0.0.0。(为空代表全部 IP 地址)
    • 每个 Serv-U FTP 服务器中的虚拟服务器由 IP 地址和端口号唯一识别,而不是依靠 IP 地址
    • 向服务器中添加“anonymous”,系统自动判定为匿名。而不是创建新域时自动添加一个“anonymous”匿名
    • 服务器最大用户数是指服务器允许同时在线的最大用户数量
    • 用户上传下载选项要求 FTP 客户端在下载信息的同时也要上传文件

    2.3.16 DNS 服务器

    • 允许客户机在发生更改时动态更新其资源记录
    • DNS 服务器中的根服务器被自动加入到系统中,不需管理员手工配置
    • 转发器是网络上的 DNS 服务器(不是路由器),用于外域名的 DNS 查询
    • 使用 nslookup 命令可以测试正向和反向查找区域
    • 主机记录的生存时间指该记录被客户端查询到,放在缓存中的持续时间

    2.3.17 DHCP 服务器

    • 负责多个网段 IP 地址分配时需配置多个作用域
    • 添加保留时需在 DHCP 客户机上获得其 MAC 地址信息(添加排除时不需从客户端获得 MAC 地址)
    • 不添加排除和保留时,服务器可将地址池内的 IP 地址动态指派给 DHCP 客户机
    • 地址池是作用域应用排除范围之后剩余的 IP 地址
    • 保留是指确保 DHCP 客户端永远可以得到同一 IP 地址,客户端可以释放该租约
    • 收到非中继转发的“DHCP发现”消息时,选择收到该消息的子网所处的网段分配 IP 地址

    2.3.18 WWW 服务器

    • Web 站点可以配置静态和动态 IP 地址
    • 访问 Web 站点时可以使用站点的域名或站点的 IP 地址
    • 建立 Web 站点时必须为该站点指定一个主目录好,也可以是虚拟的子目录
    • Web 站点的性能选项包括影响带宽使用的属性和客户端 Web 连接的数量
    • 在 Web 站点的主目录选项卡中,可配置主目录的读取和写入等权限

    2.3.19 Wmail 邮件服务器

    • Winmail 用户不可以使用 Outlook 自行注册新邮箱
    • Winmail 快速设置向导中创建新用户时,输入新建用户的信息,包括用户名、域名及用户密码(不是系统邮箱的密码)
    • 建立路由时,需在 DNS 服务器中建立该邮件服务器主机记录和邮件交换器记录
    • 邮件系统工作过程:1.用户在客户端创建新邮件;2.客户端软件使用 SMTP 协议将邮件发到发件方的邮件服务器;3.发件方邮件服务器使用 SMTP 协议将邮件发到收件方的邮件服务器;4.接收方邮件服务器将收到邮件储存待处理;5.接收方客户端软件使用 POP3 或 IMAP4 协议从邮件服务器读取邮件
    • 邮件交换器记录的配置只能在服务器上,不能通过浏览器配置
    • Winmail 支持基于 Web 方式的访问和管理,管理工具包括系统设置、域名设置等
    • 发送邮件时通常采用 SMTP 协议,接收邮件时通常采用 POP3 或者 IMAP 协议。Winmail 用户使用浏览器查看邮件会使用到 HTTP 协议

    2.3.20 PIX 防火墙

    • 监视模式中,可以更新操作系统映像和口令恢复
    • 防火墙开机自检后处于非特权模式,输入“enable”进入特权模式

    2.3.21 可信计算机评估准则

    • 没有保护就是 D类,不能用于多用户环境下重要信息处理
    • 提到用户自主保护就是 C类

    2.3.22 入侵防护系统

    • HIPS 基于主机的入侵防护系统,安装在受保护的主机系统中
    • NIPS 基于网络的入侵防护系统,布置在网络出口
    • AIPS 基于应用的入侵防护系统,部署于应用服务器前端 
      (他们的首字母 H、N、A 即 Host、Net、Application)

    2.3.23 网络攻击

    • DDos 攻击:利用已经攻占的多个系统向目标攻击,被害设备面对大量请求无法正常处理而拒绝服务
    • SYN Flooding 攻击:利用 TCP 三次握手过程,使受害主机处于会话请求之中,直至连接超时停止响应
    • SQL 注入攻击:属于利用系统漏洞,防火墙(基于网络的防护系统)无法阻断
    • Land攻击:向某个设备发送数据包,并将数据包的源 IP 地址和目的地址都设置成攻击目标的地址
    • 基于网络的防护系统也无法阻断 Cookie篡改 和 DNS欺骗
    • Tear doop 、Smurf 攻击可以被路由器阻止

    2.3.24 无线局域网设备

    • 无线接入点(AP):集合无线或者有线终端(类似于集线器和交换机),负责频段管理和漫游工作(SSID 是客户端设备用来访问接入点的唯一标识)
    • 无线路由器:具有无线路由功能和 NAT 功能的 AP ,可用来建立小的无线局域网。
    • 无线网桥:用于连接几个不同的网段,实现较远距离的无线通信(网桥最重要的维护工作是构建和维护 MAC 地址表)
    • 无线网卡:实现点对点通信,安装于各终端节点

    2.3.25 VLAN

    • VLAN name 用 1~32 个字符表示,它可以是字母和数字。不给定名字的 VLAN 系统自动按缺省的 VLAN 名(VLAN00xxx)
    • VLAN ID的取值范围是 1~4094。其中无法执行“no vlan 1”命令

    2.3.26 Cisco 路由器上的存储器

    • Flash 主要用于存储当前使用的操作系统映像文件和微代码
    • NVRAM 主要存储启动配置文件或备份配置文件
    • RAM 主要存储路由表、快速交换缓存、ARP 缓存、数据分组缓冲区和缓冲队列、运行配置文件等
    • ROM 主要用来永久保存路由器的开机诊断程序、引导程序和操作系统软件

    2.3.27 防火墙对应端口的连接方案

    pix525 在缺省情况下

    • ethernet0 被命名为外部接口 outside,安全级别是 0
    • ethernet1 被命名为内部接口 inside,安全级别是 100
    • ethernet2 被命名为中间接口 dmz,安装级别是 50

    2.3.28 STP 生成树结构

    • 无论是根的确定,还是树状结构的生成,主要依靠 BPDU 提供的信息
    • Bridge ID 由两个字节的优先级值和 6 个字节的交换机 MAC 地址组成,优先级取值范围是0~61440,增值量是4096,优先值越小,优先级越高
    • MAC 地址最小的为根网桥
    • BPDU 数据包有两种类型,配置 BPDU 不超过 35 个字节,拓扑变化通知 BPDU 不超过 4 个字节

    2.3.29 Catelyst 配置命令

    • Catelyst3548 设置时间的格式是:clock set 小时:分钟:秒 日 月 年
    • Catelyst6500 设置时间的格式是:set time 星期 月/日/年 小时 分钟 秒

    2.3.30 其他

    有一些知识点因为考频不是很高或者比较复杂,就不写了,自己做题时积累或者放弃。

    在遇到陌生题目时,试着结合常识思考推断。 
    比如说,某网络计划有三台计算机,但只有一个 VALN 端口,需要的设备是() 
    这里需要的其实就是路由器,联想宿舍上网的情况

    3.大题(前四道每道10分,最后一道20分)

    3.1 第一道 填地址表

    例:

    IP 地址115.151.29.58
    子网掩码255.240.0.0
    地址类别【1】
    网络地址【2】
    直接广播地址【3】
    主机号【4】
    子网内第一个可用 IP 地址【5】

    解:

    IP 地址类别IP 首段范围
    A类1~127
    B类128~191
    C类192~223

    则【1】填:A类 
    对 IP地址和子网掩码做如下处理: 

    熟练以后其实没有看起来这么麻烦,做两道就会了。少数情况会给出表格的后两项,让你补充前五项,原理其实是一样的,倒推一下。 
    这道题是大题里面考点最稳定的一道,必须掌握。

    3.2 第二道 配置路由器

    例: 



    一般就考这些空,做几道之后就能填上大部分,小部分可以放弃。

    3.3 第三道 DHCP 报文

    例: 
     

    3.4 第四道 sniffer 数据包

    例1: 

    根据图中信息回答以下问题

    1. 该主机执行的命令是( ),该主机配置的 DNS 服务器的 IP 地址是( ) 
      解:看图中有 ICMP 几个字母,还有个邮箱地址,所以命令是 tracert mail.tj.edu.cn,DNS服务器的 IP 地址是第一行第二个地址 202.113.64.3(只要这么问,就基本是第一行第二个)
    2. 图中 ② ③ ④ 处分别是( ) 
      解:② 处前面 Protocol 意思是协议,协议就是 ICMP;③ 写源地址,就是第一行第一个地址 202.113.64.137;④ Destination address 意思是目的地址,这个位置应该写题中有的网址 mail.tj.edu.cn。

    例2: 

    根据图中信息回答以下问题

    1. 该主机配置的域名服务器的 IP 地址是( ) 
      解:和上题一样,还是第一行第二个 202.113.64.3
    2. ① 处的信息应该是( ) 
      解:填 ACK。一般都是有一个 SEQ,后再有一个 ACK,接着再有 SEQ,再有 ACK。他们的数值每次 +1,有时候会根据上下行填数字。
    3. 主机 202.38.97.197 是( )服务器,其提供服务的端口是( ) 
      解:因为图中有 FTP 几个字母,所以这是 ftp服务器;提供服务的端口是 21(DNS服务器的端口是 53,邮件服务器的端口是 6)
    4. 该主机执行的命令是( ) 
      解:填 ftp ftp.pku.edu.cn(网站在图中,前面加 ftp)

    这道题通常就考上面这两种模式,一种有 ICMP 对应 tracert mail.tj.edu.cn 的,一种有 FTP 对应 ftp ftp.pku.edu.cn 的。 
    如果让写 URL 就是 https :// mail.tj.edu.cn 或者 ftp :// ftp.pku.edu.cn(中间都没有空格,我为了格式不自动转换成链接才加的)

    第四道大题也是考点很不稳定的一道。

    3.5 最后一道

    3.5.1 填表部分(12分)

    目的网络/掩码长度输出端口
    【1】S0(直接连接)
    【2】S1(直接连接)
    【3】S0
    【4】S1
    【5】S0
    【6】S1

    解:图中最上方的 RG 有两个分支,左侧分支是 S0 ,有末段为 129 和 130 的两个地址,进行聚合: 

    所以【1】处填 192.168.6.128/30 ;同理【2】处是 192.168.6.133 和 192.168.6.134 聚合,结果为 192.168.6.132/30。 
    做题实际上只要写出最后那段就行,前面选择题时已经说过了。

    【3】是 RE 下方 192.168.6.65、192.168.6.66、192.168.6.67 三个子网的聚合; 
    【4】是 RF 下方 192.168.6.80、192.168.6.81、192.168.6.82 三个子网的聚合; 
    【5】是 左下方 192.168.64.0/24、192.168.65.0/24、192.168.66.0/24、192.168.67.0/24 四个地址块的聚合; 
    【6】是 右下方 192.168.96.0/24、192.168.97.0/24、192.168.98.0/24、192.168.99.0/24 四个地址块的聚合;

    在【3】【4】两空聚合时往往需要多注意 


    最终答案应为 
    【3】192.168.6.64/29 
    【4】192.168.6.64/27 
    【5】192.168.64.0/22 
    【6】192.168.96.0/22

    这个填表是必拿分的题。

    3.5.2 中间部分(2~4分)

    这部分考点很不固定,下面是频率稍高的,考试这几分放弃也可以

    • 问在某路由器上,最多还可链接的路由器数量是多少。如果所在子网掩码是 /29 就填 3,是 /28 就填 11。
    • 问串接一种设备能监听路由器之间的流量,写 TAP
    • 问串接一种设备能提供安全保护,一般是 IPS
    • 问防火墙访问外网设置,分别填 nat 和 global

    3.5.3 计算子网掩码和 IP 段部分(4~6分)

    例:将 192.168.66.128/25 划分为三个子网,子网 1 能容纳 50 台主机,子网 2 和 3 能分别容纳 20 台主机……求他们的子网掩码和可用 IP 地址段

    解:题中说多少台主机的具体数字不重要,刚好大于那个数字的 2 的 n 次方的数才重要。 
    比如 50 台,就是 64,是 2 的 6 次方。所以子网掩码后 6 位都是 0 (前面全是 1 ),11111111.11111111.11111111.11000000 ,最后填空写 255.255.255.192 
    同理 20 台,就是 32,是 2 的 5次方。所以子网掩码后 5位都是 0,最后填空 2 和 3 的子网掩码都是 255.255.255.224

    可用 IP 地址从题目所给的那个数 +1 开始,本题是 192.168.66.129(因为太乱,下面只写末段数字,反正前面都一样) 
    从 129 开始,因为子网 1 的那个数字是 64 ,所以到 190 结束(129+64-3=190,不用管为什么,结束都是 -3) 
    下一段从 193 开始(190+3=193,不用管为什么,开始都是 +3),因为子网 2 的那个数字是 32 ,所以到 222 结束(193+32-3=222) 
    再下一段从 225 开始(222+3=225),因为子网 3 的那个数字也是 32 ,所以到 254 结束(225+32-3=254) 
    写成答案分别为: 
    子网 1 的可用 IP 地址段为 192.168.66.129~192.168.66.190 
    子网 2 的可用 IP 地址段为 192.168.66.193~192.168.66.222 
    子网 3 的可用 IP 地址段为 192.168.66.225~192.168.66.254

    看起来上面写了一大堆,其实明白了就很简单,这个也是必拿分的题。


    总结:得分策略

    目标是通过考试,也就是 60 分

    • 选择题部分:前面一共写了 10 个做法固定的“第一类选择题”,还有 19 个“第三类选择题”的高频考点,加上“第二类选择题”。选择题得分在 20 分以上是很保守的估计,没有意外的话选择题应该在 25 分以上。
    • 大题部分:第一道的 10 分是必得的,最后一道除了中间部分后有 16 分是必得的。从前面写的也能看出第二、三、四道大题的考点不是特别固定,所以尽量写,填对一半就很好了(其实也没有那么难),所以这三道大题 30 分目标是得 15 分。

    来算一下 20 + 10 + 16 + 15 = 61 分。实际情况当然可能会出现意外,比如三道大题没得到 15 分,但刚才也没算你蒙对的题得分。

    多练习几套题,来回对照着知识点就熟悉了,这个考试题型固定,含金量不高,难度不大,不用害怕。题库软件有很多缺陷,比如大题评分不准、填空题缺少空格,甚至是答案错误。自己要注意核对。这份文档并未涵盖所有知识点,多做一套题就多了一分考过的把握。

    (未来教育题库的第九套题有点特殊,看起来像 13 年考试改革之前的老题,和其他套的题有很大差别,留意一下。)

    完。 
    2017/3/19 初版 
    2017/4/25 修改了前言与总结 
    2017/5/12 修改内容略 
    2017/5/16 刚查到成绩,84分,本来还以为能上90… 
    2017/8/23 补充了备考建议 
    2017/9/12 改正了 2.1.6 IP地址块聚合 
    2017/9/21 增加了 2.3 中近一半的内容,感谢佚名进行的补充 
    2017/12/18 考试获证条件改变,三级不再需要对应的二级科目通过

     

    展开全文
  • 八月份参加了中科院计算所的面试,结果不幸悲剧。本着对自己负责任的态度,不能在同个地方摔倒,特在直接把我发现的篇不错的贴直接粘过来了....(转自网易博客---银河里的星星),好好研究,细心学习啊。 ...
       八月份参加了中科院计算所的面试,结果不幸悲剧。本着对自己负责任的态度,不能在同一个地方摔倒,特在直接把我发现的一篇不错的贴直接粘过来了....(转自网易博客---银河里的星星),好好研究,细心学习啊。
    

    一个http请求的详细过程

    我们来看当我们在浏览器输入http://www.mycompany.com:8080/mydir/index.html,幕后所发生的一切。

    首先http是一个应用层的协议,在这个层的协议,只是一种通讯规范,也就是因为双方要进行通讯,大家要事先约定一个规范。

    1.连接 当我们输入这样一个请求时,首先要建立一个socket连接,因为socket是通过ip和端口建立的,所以之前还有一个DNS解析过程,把www.mycompany.com变成ip,如果url里不包含端口号,则会使用该协议的默认端口号。

    DNS的过程是这样的:首先我们知道我们本地的机器上在配置网络时都会填写DNS,这样本机就会把这个url发给这个配置的DNS服务器,如果能够找到相应的url则返回其ip,否则该DNS将继续将该解析请求发送给上级DNS,整个DNS可以看做是一个树状结构,该请求将一直发送到根直到得到结果。现在已经拥有了目标ip和端口号,这样我们就可以打开socket连接了。

    2.请求 连接成功建立后,开始向web服务器发送请求,这个请求一般是GET或POST命令(POST用于FORM参数的传递)。GET命令的格式为:  GET 路径/文件名 HTTP/1.0 文件名指出所访问的文件,HTTP/1.0指出Web浏览器使用的HTTP版本。现在可以发送GET命令:

    GET /mydir/index.html HTTP/1.0,

    3.应答 web服务器收到这个请求,进行处理。从它的文档空间中搜索子目录mydir的文件index.html。如果找到该文件,Web服务器把该文件内容传送给相应的Web浏览器。

    为了告知浏览器,,Web服务器首先传送一些HTTP头信息,然后传送具体内容(即HTTP体信息),HTTP头信息和HTTP体信息之间用一个空行分开。 常用的HTTP头信息有:   ① HTTP 1.0 200 OK  这是Web服务器应答的第一行,列出服务器正在运行的HTTP版本号和应答代码。代码"200 OK"表示请求完成。   ② MIME_Version:1.0 它指示MIME类型的版本。   ③ content_type:类型 这个头信息非常重要,它指示HTTP体信息的MIME类型。如:content_type:text/html指示传送的数据是HTML文档。   ④ content_length:长度值 它指示HTTP体信息的长度(字节)。

    4.关闭连接:当应答结束后,Web浏览器与Web服务器必须断开,以保证其它Web浏览器能够与Web服务器建立连接。

    下面我们具体分析其中的数据包在网络中漫游的经历

    在网络分层结构中,各层之间是严格单向依赖的。“服务”是描述各层之间关系的抽象概念,即网络中各层向紧邻上层提供的一组操作。下层是服务提供者,上层是请求服务的用户。服务的表现形式是原语(primitive),如系统调用或库函数。系统调用是操作系统内核向网络应用程序或高层协议提供的服务原语。网络中的n层总要向n+1层提供比n-1层更完备的服务,否则n层就没有存在的价值。

    传输层实现的是“端到端”通信,引进网间进程通信概念,同时也要解决差错控制,流量控制,数据排序(报文排序),连接管理等问题,为此提供不同的服务方式。通常传输层的服务通过系统调用的方式提供,以socket的方式。对于客户端,要想建立一个socket连接,需要调用这样一些函数socket() bind() connect(),然后就可以通过send()进行数据发送。

    现在看数据包在网络中的穿行过程:

    应用层

    首先我们可以看到在应用层,根据当前的需求和动作,结合应用层的协议,有我们确定发送的数据内容,我们把这些数据放到一个缓冲区内,然后形成了应用层的报文data

    传输层

    这些数据通过传输层发送,比如tcp协议。所以它们会被送到传输层处理,在这里报文打上了传输头的包头,主要包含端口号,以及tcp的各种制信息,这些信息是直接得到的,因为接口中需要指定端口。这样就组成了tcp的数据传送单位segment。tcp是一种端到端的协议,利用这些信息,比如tcp首部中的序号确认序号,根据这些数字,发送的一方不断的进行发送等待确认,发送一个数据段后,会开启一个计数器,只有当收到确认后才会发送下一个,如果超过计数时间仍未收到确认则进行重发,在接受端如果收到错误数据,则将其丢弃,这将导致发送端超时重发。通过tcp协议,控制了数据包的发送序列的产生,不断的调整发送序列,实现流控和数据完整。

    网络层

    然后待发送的数据段送到网络层,在网络层被打包,这样封装上了网络层的包头,包头内部含有源及目的的ip地址,该层数据发送单位被称为packet。网络层开始负责将这样的数据包在网络上传输,如何穿过路由器,最终到达目的地址。在这里,根据目的ip地址,就需要查找下一跳路由的地址。首先在本机,要查找本机的路由表,在windows上运行route print就可以看到当前路由表内容,有如下几项: Active Routes Default Route Persistent Route.

    整个查找过程是这样的: (1)根据目的地址,得到目的网络号,如果处在同一个内网,则可以直接发送。 (2)如果不是,则查询路由表,找到一个路由。 (3)如果找不到明确的路由,此时在路由表中还会有默认网关,也可称为缺省网关,IP用缺省的网关地址将一个数据传送给下一个指定的路由器,所以网关也可能是路由器,也可能只是内网向特定路由器传输数据的网关。 (4)路由器收到数据后,它再次为远程主机或网络查询路由,若还未找到路由,该数据包将发送到该路由器的缺省网关地址。而数据包中包含一个最大路由跳数,如果超过这个跳数,就会丢弃数据包,这样可以防止无限传递。路由器收到数据包后,只会查看网络层的包裹数据,目的ip。所以说它是工作在网络层,传输层的数据对它来说则是透明的。

    如果上面这些步骤都没有成功,那么该数据报就不能被传送。如果不能传送的数据报来自本机,那么一般会向生成数据报的应用程序返回一个“主机不可达”或 “网络不可达”的错误。

     

    以windows下主机的路由表为例,看路由的查找过程 ====================================================================== Active Routes: Network Destination            Netmask                      Gateway              Interface                  Metric 0.0.0.0                                 0.0.0.0                       192.168.1.2           192.168.1.101           10 127.0.0.0                             255.0.0.0                   127.0.0.1               127.0.0.1                   1 192.168.1.0                         255.255.255.0           192.168.1.101       192.168.1.101           10 192.168.1.101                     255.255.255.255       127.0.0.1               127.0.0.1                   10 192.168.1.255                     255.255.255.255       192.168.1.101       192.168.1.101           10  224.0.0.0                            240.0.0.0                   192.168.1.101       192.168.1.101           10 255.255.255.255                 255.255.255.255       192.168.1.101       192.168.1.101           1 Default Gateway:                192.168.1.2

    Network Destination 目的网段  Netmask 子网掩码  Gateway 下一跳路由器入口的ip,路由器通过interface和gateway定义一调到下一个路由器的链路,通常情况下,interface和gateway是同一网段的。 Interface 到达该目的地的本路由器的出口ip(对于我们的个人pc来说,通常由机算机A的网卡,用该网卡的IP地址标识,当然一个pc也可以有多个网卡)。

    网关这个概念,主要用于不同子网间的交互,当两个子网内主机A,B要进行通讯时,首先A要将数据发送到它的本地网关,然后网关再将数据发送给B所在的网关,然后网关再发送给B。 默认网关,当一个数据包的目的网段不在你的路由记录中,那么,你的路由器该把那个数据包发送到哪里!缺省路由的网关是由你的连接上的default gateway决定的,也就是我们通常在网络连接里配置的那个值。

    通常interface和gateway处在一个子网内,对于路由器来说,因为可能具有不同的interface,当数据包到达时,根据Network Destination寻找匹配的条目,如果找到,interface则指明了应当从该路由器的那个接口出去,gateway则代表了那个子网的网关地址。

    第一条      0.0.0.0   0.0.0.0   192.168.1.2    192.168.1.101   10 0.0.0.0代表了缺省路由。该路由记录的意思是:当我接收到一个数据包的目的网段不在我的路由记录中,我会将该数据包通过192.168.1.101这个接口发送到192.168.1.2这个地址,这个地址是下一个路由器的一个接口,这样这个数据包就可以交付给下一个路由器处理,与我无关。该路由记录的线路质量 10。当有多个条目匹配时,会选择具有较小Metric值的那个。

    第三条      192.168.1.0   255.255.255.0  192.168.1.101   192.168.1.101  10 直联网段的路由记录:当路由器收到发往直联网段的数据包时该如何处理,这种情况,路由记录的interface和gateway是同一个。当我接收到一个数据包的目的网段是192.168.1.0时,我会将该数据包通过192.168.1.101这个接口直接发送出去,因为这个端口直接连接着192.168.1.0这个网段,该路由记录的线路质量 10 (因interface和gateway是同一个,表示数据包直接传送给目的地址,不需要再转给路由器)。

    一般就分这两种情况,目的地址与当前路由器接口是否在同一子网。如果是则直接发送,不需再转给路由器,否则还需要转发给下一个路由器继续进行处理。

     

    查找到下一跳ip地址后,还需要知道它的mac地址,这个地址要作为链路层数据装进链路层头部。这时需要arp协议,具体过程是这样的,查找arp缓冲,windows下运行arp -a可以查看当前arp缓冲内容。如果里面含有对应ip的mac地址,则直接返回。否则需要发生arp请求,该请求包含源的ip和mac地址,还有目的地的ip地址,在网内进行广播,所有的主机会检查自己的ip与该请求中的目的ip是否一样,如果刚好对应则返回自己的mac地址,同时将请求者的ip mac保存。这样就得到了目标ip的mac地址。

    链路层

    将mac地址及链路层控制信息加到数据包里,形成Frame,Frame在链路层协议下,完成了相邻的节点间的数据传输,完成连接建立,控制传输速度,数据完整。

    物理层

    物理线路则只负责该数据以bit为单位从主机传输到下一个目的地。

    下一个目的地接受到数据后,从物理层得到数据然后经过逐层的解包 到 链路层 到 网络层,然后开始上述的处理,在经网络层 链路层 物理层将数据封装好继续传往下一个地址。

    在上面的过程中,可以看到有一个路由表查询过程,而这个路由表的建立则依赖于路由算法。也就是说路由算法实际上只是用来路由器之间更新维护路由表,真正的数据传输过程并不执行这个算法,只查看路由表。这个概念也很重要,需要理解常用的路由算法。而整个tcp协议比较复杂,跟链路层的协议有些相似,其中有很重要的一些机制或者概念需要认真理解,比如编号与确认,流量控制,重发机制,发送接受窗口。

     

    tcp/ip基本模型及概念

    物理层

    设备,中继器(repeater),集线器(hub)。对于这一层来说,从一个端口收到数据,会转发到所有端口。

    链路层

    协议:SDLC(Synchronous Data Link Control)HDLC(High-level Data Link Control) ppp协议独立的链路设备中最常见的当属网卡,网桥也是链路产品。集线器MODEM的某些功能有人认为属于链路层,对此还有些争议认为属于物理层设备。除此之外,所有的交换机都需要工作在数据链路层,但仅工作在数据链路层的仅是二层交换机。其他像三层交换机、四层交换机和七层交换机虽然可对应工作在OSI的三层、四层和七层,但二层功能仍是它们基本的功能。

    因为有了MAC地址表,所以才充分避免了冲突,因为交换机通过目的MAC地址知道应该把这个数据转发到哪个端口。而不会像HUB一样,会转发到所有滴端口。所以,交换机是可以划分冲突域滴。

    网络层

    四个主要的协议:   网际协议IP:负责在主机和网络之间寻址和路由数据包。     地址解析协议ARP:获得同一物理网络中的硬件主机地址。     网际控制消息协议ICMP:发送消息,并报告有关数据包的传送错误。     互联组管理协议IGMP:被IP主机拿来向本地多路广播路由器报告主机组成员。

    该层设备有三层交换机,路由器。

    传输层

    两个重要协议 TCP 和 UDP 。

    端口概念:TCP/UDP 使用 IP 地址标识网上主机,使用端口号来标识应用进程,即 TCP/UDP 用主机 IP 地址和为应用进程分配的端口号来标识应用进程。端口号是 16 位的无符号整数, TCP 的端口号和 UDP 的端口号是两个独立的序列。尽管相互独立,如果 TCP 和 UDP 同时提供某种知名服务,两个协议通常选择相同的端口号。这纯粹是为了使用方便,而不是协议本身的要求。利用端口号,一台主机上多个进程可以同时使用 TCP/UDP 提供的传输服务,并且这种通信是端到端的,它的数据由 IP 传递,但与 IP 数据报的传递路径无关。网络通信中用一个三元组可以在全局唯一标志一个应用进程:(协议,本地地址,本地端口号)。

    也就是说tcp和udp可以使用相同的端口。

    可以看到通过(协议,源端口,源ip,目的端口,目的ip)就可以用来完全标识一组网络连接。

    应用层

    基于tcp:Telnet FTP SMTP DNS HTTP 基于udp:RIP NTP(网落时间协议)和DNS (DNS也使用TCP)SNMP TFTP

     

    参考文献:

    转自博客http://www.cnblogs.com/xiaoliyu/archive/2009/10/15/1583921.html

    读懂本机路由表 http://hi.baidu.com/thusness/blog/item/9c18e5bf33725f0818d81f52.html

    Internet 传输层协议 http://www.cic.tsinghua.edu.cn/jdx/book6/3.htm

    计算机网络 谢希仁

    展开全文
  • 转自:python爬虫 - python requests网络请求简洁之道 requests简介 requests是个很实用的Python HTTP客户端库,编写爬虫和测试服务器响应数据时经常会用到。大神kennethreitz的作品,简易明了的HTTP请求...

    转自:python爬虫 - python requests网络请求简洁之道

    requests简介

    requests是一个很实用的Python HTTP客户端库,编写爬虫和测试服务器响应数据时经常会用到。大神kennethreitz的作品,简易明了的HTTP请求操作库, 是urllib2的理想替代品。requests is an elegant HTTP library。API简洁明了,这才是Python开发者喜欢的。

    requests跟urllib,urllib2类似,但是python的标准库urllib2提供了大部分需要的HTTP功能,但是API太逆天了,一个简单的功能就需要一大堆代码。

    Requests 使用的是 urllib3,因此继承了它的所有特性。Requests 支持 HTTP 连接保持和连接池,支持使用 cookie 保持会话,支持文件上传,支持自动确定响应内容的编码,支持国际化的 URL 和 POST 数据自动编码。现代、国际化、人性化。

    requests的功能特性
    Requests 完全满足如今网络的需求:
    国际化域名和 URLs
    Keep-Alive & 连接池
    持久的 Cookie 会话
    类浏览器式的 SSL 加密认证
    基本/摘要式的身份认证
    优雅的键/值 Cookies
    自动解压
    Unicode 编码的响应体
    多段文件上传
    连接超时
    支持 .netrc
    适用于 Python 2.6—3.4
    线程安全

    >>> r = requests.get('https://api.github.com/user', auth=('user', 'pass'))
    >>> r.status_code
    200
    >>> r.headers['content-type']
    'application/json; charset=utf8'
    >>> r.encoding
    'utf-8'
    >>> r.text
    u'{"type":"User"...'
    >>> r.json()
    {u'private_gists': 419, u'total_private_repos': 77, ...}

    皮皮Blog



    requests和python自带urllib的对比

    py2:

    [python]  view plain  copy
     print ? 在CODE上查看代码片 派生到我的代码片
    1. #!/usr/bin/env python  
    2. # -*- coding: utf-8 -*-  
    3.   
    4. import urllib2  
    5.   
    6. gh_url = 'https://api.github.com'  
    7.   
    8. req = urllib2.Request(gh_url)  
    9.   
    10. password_manager = urllib2.HTTPPasswordMgrWithDefaultRealm()  
    11. password_manager.add_password(None, gh_url, 'user''pass')  
    12.   
    13. auth_manager = urllib2.HTTPBasicAuthHandler(password_manager)  
    14. opener = urllib2.build_opener(auth_manager)  
    15.   
    16. urllib2.install_opener(opener)  
    17.   
    18. handler = urllib2.urlopen(req)  
    19.   
    20. print handler.getcode()  
    21. print handler.headers.getheader('content-type')  
    22.   
    23. # ------  
    24. # 200  
    25. # 'application/json'  
    requests

    [python]  view plain  copy
     print ? 在CODE上查看代码片 派生到我的代码片
    1. #!/usr/bin/env python  
    2. # -*- coding: utf-8 -*-  
    3.   
    4. import requests  
    5.   
    6. r = requests.get('https://api.github.com', auth=('user''pass'))  
    7.   
    8. print r.status_code  
    9. print r.headers['content-type']  
    10.   
    11. # ------  
    12. # 200  
    13. # 'application/json'  
    皮皮Blog

    [urllib2 vs requests]



    requests使用举栗

    安装

    pip install requests


    基本使用

      >>>import requests
    >>> r = requests.get('http://www.****.com') # 发送请求
    >>> r.status_code # 返回码 200
    >>> r.headers['content-type'] # 返回头部信息'text/html; charset=utf8'
    >>> r.encoding # 编码信息'utf-8'
    >>> r.text #内容部分(如果存在编码问题,也可以使用r.content,见下面的编码问题部分)
    u'<!DOCTYPE html>\n<html xmlns="http://www.***/xhtml"...'...


    各种不同HTTP请求

      >>> r = requests.post("http://httpbin.org/post")
    >>> r = requests.put("http://httpbin.org/put")
    >>> r = requests.delete("http://httpbin.org/delete")
    >>> r = requests.head("http://httpbin.org/get")
    >>> r = requests.options("http://httpbin.org/get")


    带参数的请求

      >>> payload = {'wd': '张亚楠', 'rn': '100'}
    >>> r = requests.get("http://www.baidu.com/s", params=payload)
    >>> print r.url
    u'http://www.baidu.com/s?rn=100&wd=%E5%BC%A0%E4%BA%9A%E6%A5%A0'

    Note: 这里的params可以不用自己进行urlencode的。


    获取json结果

      >>>r = requests.get('...')
      >>>r.json()['data']['country']
      '中国'
     
    
    >>> r = requests.get('https://github.com/timeline.json')
    >>> r.json()
    [{u'repository': {u'open_issues': 0, u'url': 'https://github.com/...

    Note: 实际内容:{"message":"Hello there, wayfaring stranger......","documentation_url":"https://developer.github.com/v3/..."}

    皮皮Blog

    requests库的编码问题

    Request 对象在访问服务器后会返回一个Response对象,这个对象将返回的Http响应字节码保存到content属性中。

    但是如果你访问另一个属性text时,会返回一个unicode对象,乱码问题就会常常发成在这里。因为Response对象会通过另一个属性encoding来将字节码编码成unicode,而这个encoding属性居然是responses自己猜出来的。

    官方文档:

    text
    Content of the response, in unicode.
    If Response.encoding is None, encoding will be guessed using chardet.
    The encoding of the response content is determined based solely on HTTP headers, following RFC 2616 to the letter. If you can take advantage of non-HTTP knowledge to make a better guess at the encoding, you should set r.encoding appropriately before accessing this property.
    

    所以要么你直接使用content(字节码),要么记得把encoding设置正确。

    比如获取一段gbk编码的网页,就需要以下方法才能得到正确的unicode

    [python]  view plain  copy
     print ? 在CODE上查看代码片 派生到我的代码片
    1. import requests  
    2. url = "http://xxx.xxx.xxx"  
    3.   
    4. response = requests.get(url)  
    5. response.encoding = 'gbk'  
    6. print response.text  
    皮皮Blog



    python3 httplib2

    不过小编皮皮告诉大家另一种python3的简洁网络请求之道

    [python]  view plain  copy
     print ? 在CODE上查看代码片 派生到我的代码片
    1. import httplib2  
    2.   
    3. h = httplib2.Http(".cache")  
    4. h.add_credentials('user''pass')  
    5. r, content = h.request("https://api.github.com""GET")  
    6.   
    7. print r['status']  
    8. print r['content-type']  
    Note : 也是等同requests的几行代码啊! [urllib2 vs requests ]

    from:http://blog.csdn.net/pipisorry/article/details/48086195

    ref:Requests: HTTP for Humans

    requests快速上手

    [https://github.com/kennethreitz/requests]



    现代浏览器的工作原理


    简介

    浏览器可以被认为是使用最广泛的软件,本文将介绍浏览器的工 作原理,我们将看到,从你在地址栏输入google.com到你看到google主页过程中都发生了什么。

    将讨论的浏览器

    今天,有五种主流浏览器——IE、Firefox、Safari、Chrome及Opera。本文将基于一些开源浏览器的例子——Firefox、 Chrome及Safari,Safari是部分开源的。

    根据W3C(World Wide Web Consortium 万维网联盟)的浏览器统计数据,当前(2011年9月),Firefox、Safari及Chrome的市场占有率综合已快接近50%。(原文为2009年10月,数据没有太大变化)因此,可以说开源浏览器将近占据了浏览器市场的半壁江山。

    浏览器的主要功能

    浏览器的主要功能是将用户选择得web资源呈现出来,它需要从服务器请求资源,并将其显示在浏览器窗口中,资源的格式通常是HTML,也包括PDF、image及其他格式。用户用URI(Uniform Resource Identifier 统一资源标识符)来指定所请求资源的位置,在网络一章有更多讨论。

    HTML和CSS规范中规定了浏览器解释html文档的方式,由 W3C组织对这些规范进行维护,W3C是负责制定web标准的组织。

    HTML规范的最新版本是HTML4(http://www.w3.org/TR/html401/),HTML5还在制定中(译注:两年前),最新的CSS规范版本是2(http://www.w3.org/TR/CSS2),CSS3也还正在制定中(译注:同样两年前)。

    这些年来,浏览器厂商纷纷开发自己的扩展,对规范的遵循并不完善,这为web开发者带来了严重的兼容性问题。

    但是,浏览器的用户界面则差不多,常见的用户界面元素包括:

    • ▲用来输入URI的地址栏
    • ▲前进、后退按钮
    • ▲书签选项
    • ▲用于刷新及暂停当前加载文档的刷新、暂停按钮
    • ▲用于到达主页的主页按钮

    奇怪的是,并没有哪个正式公布的规范对用户界面做出规定,这些是多年来各浏览器厂商之间相互模仿和不断改进得结果。

    HTML5并没有规定浏览器必须具有的UI元素,但列出了一些常用元素,包括地址栏、状态栏及工具栏。还有一些浏览器有自己专有得功能,比如Firefox得下载管理。更多相关内容将在后面讨论用户界面时介绍。

    浏览器的主要构成High Level Structure

    浏览器的主要组件包括:

    • 用户界面- 包括地址栏、后退/前进按钮、书签目录等,也就是你所看到的除了用来显示你所请求页面的主窗口之外的其他部分
    • 浏览器引擎- 用来查询及操作渲染引擎的接口
    • 渲染引擎- 用来显示请求的内容,例如,如果请求内容为html,它负责解析html及css,并将解析后的结果显示出来
    • 网络- 用来完成网络调用,例如http请求,它具有平台无关的接口,可以在不同平台上工作
    • UI 后端- 用来绘制类似组合选择框及对话框等基本组件,具有不特定于某个平台的通用接口,底层使用操作系统的用户接口
    • JS解释器- 用来解释执行JS代码
    • 数据存储- 属于持久层,浏览器需要在硬盘中保存类似cookie的各种数据,HTML5定义了web database技术,这是一种轻量级完整的客户端存储技术

    现代浏览器的工作原理

    图1:浏览器主要组件

    需要注意的是,不同于大部分浏览器,Chrome为每个Tab分配了各自的渲染引擎实例,每个Tab就是一个独立的进程。

    对于构成浏览器的这些组件,后面会逐一详细讨论。

    组件间的通信 Communication between the components

    Firefox和Chrome都开发了一个特殊的通信结构,后面将有专门的一章进行讨论。

    渲染引擎 The rendering engine

    渲染引擎的职责就是渲染,即在浏览器窗口中显示所请求的内容。

    默认情况下,渲染引擎可以显示html、xml文档及图片,它也可以借助插件(一种浏览器扩展)显示其他类型数据,例如使用PDF阅读器插件,可以显示PDF格式,将由专门一章讲解插件及扩展,这里只讨论渲染引擎最主要的用途——显示应用了CSS之后的html及图片。

    渲染引擎 Rendering engines

    本文所讨论得浏览器——Firefox、Chrome和Safari是基于两种渲染引擎构建的,Firefox使用Geoko——Mozilla自主研发的渲染引擎,Safari和Chrome都使用webkit。

    Webkit是一款开源渲染引擎,它本来是为linux平台研发的,后来由Apple移植到Mac及Windows上,相关内容请参考http://webkit.org

    主流程 The main flow

    渲染引擎首先通过网络获得所请求文档的内容,通常以8K分块的方式完成。

    下面是渲染引擎在取得内容之后的基本流程:

    解析html以构建dom树->构建render树->布局render树->绘制render树

    现代浏览器的工作原理

    图2:渲染引擎基本流程

    渲染引擎开始解析html,并将标签转化为内容树中的dom节点。接着,它解析外部CSS文件及style标签中的样式信息。这些样式信息以及html中的可见性指令将被用来构建另一棵树——render树。

    Render树由一些包含有颜色和大小等属性的矩形组成,它们将被按照正确的顺序显示到屏幕上。

    Render树构建好了之后,将会执行布局过程,它将确定每个节点在屏幕上的确切坐标。再下一步就是绘制,即遍历render树,并使用UI后端层绘制每个节点。

    值得注意的是,这个过程是逐步完成的,为了更好的用户体验,渲染引擎将会尽可能早的将内容呈现到屏幕上,并不会等到所有的html都解析完成之后再去构建和布局render树。它是解析完一部分内容就显示一部分内容,同时,可能还在通过网络下载其余内容。

     现代浏览器的工作原理

    图3:webkit主流程

     现代浏览器的工作原理

    图4:Mozilla的Geoko 渲染引擎主流程

    从图3和4中可以看出,尽管webkit和Gecko使用的术语稍有不同,他们的主要流程基本相同。Gecko称可见的格式化元素组成的树为frame树,每个元素都是一个frame,webkit则使用render树这个名词来命名由渲染对象组成的树。Webkit中元素的定位称为布局,而Gecko中称为回流。Webkit称利用dom节点及样式信息去构建render树的过程为attachment,Gecko在html和dom树之间附加了一层,这层称为内容接收器,相当制造dom元素的工厂。下面将讨论流程中的各个阶段。

    解析 Parsing-general

    既然解析是渲染引擎中一个非常重要的过程,我们将稍微深入的研究它。首先简要介绍一下解析。

    解析一个文档即将其转换为具有一定意义的结构——编码可以理解和使用的东西。解析的结果通常是表达文档结构的节点树,称为解析树或语法树。

    例如,解析“2+3-1”这个表达式,可能返回这样一棵树。

    现代浏览器的工作原理

    图5:数学表达式树节点

    文法 Grammars

    解析基于文档依据的语法规则——文档的语言或格式。每种可被解析的格式必须具有由词汇及语法规则组成的特定的文法,称为上下文无关文法。人类语言不具有这一特性,因此不能被一般的解析技术所解析。

    解析器-词法分析器 Parser-Lexer combination

    解析可以分为两个子过程——语法分析及词法分析

    词法分析就是将输入分解为符号,符号是语言的词汇表——基本有效单元的集合。对于人类语言来说,它相当于我们字典中出现的所有单词。

    语法分析指对语言应用语法规则。

    解析器一般将工作分配给两个组件——词法分析器(有时也叫分词器)负责将输入分解为合法的符号,解析器则根据语言的语法规则分析文档结构,从而构建解析树,词法分析器知道怎么跳过空白和换行之类的无关字符。

    现代浏览器的工作原理

    图6:从源文档到解析树

    解析过程是迭代的,解析器从词法分析器处取道一个新的符号,并试着用这个符号匹配一条语法规则, 如果匹配了一条规则,这个符号对应的节点将被添加到解析树上,然后解析器请求另一个符号。如果没有匹配到规则,解析器将在内部保存该符号,并从词法分析器 取下一个符号,直到所有内部保存的符号能够匹配一项语法规则。如果最终没有找到匹配的规则,解析器将抛出一个异常,这意味着文档无效或是包含语法错误。

    转换 Translation

    很多时候,解析树并不是最终结果。解析一般在转换中使用——将输入文档转换为另一种格式。编译就是个例子,编译器在将一段源码编译为机器码的时候,先将源码解析为解析树,然后将该树转换为一个机器码文档。

    现代浏览器的工作原理

    图7:编译流程

    解析实例 Parsing example

    图5中,我们从一个数学表达式构建了一个解析树,这里定义一个简单的数学语言来看下解析过程。

    词汇表:我们的语言包括整数、加号及减号。

    语法:

    1. 该语言的语法基本单元包括表达式、term及操作符

    2. 该语言可以包括多个表达式

    3. 一个表达式定义为两个term通过一个操作符连接

    4. 操作符可以是加号或减号

    5. term可以是一个整数或一个表达式

    现在来分析一下“2+3-1”这个输入

    第一个匹配规则的子字符串是“2”,根据规则5,它是一个term,第二个匹配的是“2+3”,它符合第2条规则——一个操作符连接两个term,下一次匹配发生在输入的结束处。“2+3-1”是一个表达式,因为我们已经知道“2+3”是一个term,所以我们有了一个term紧跟着一个操作符及另一个term。“2++”将不会匹配任何规则,因此是一个无效输入。

    词汇表及语法的定义

    词汇表通常利用正则表达式来定义。

    例如上面的语言可以定义为:

     

    正如看到的,这里用正则表达式定义整数。

    语法通常用BNF格式定义,我们的语言可以定义为:

     

    如果一个语言的文法是上下文无关的,则它可以用正则解析器来解析。对上下文无关文法的一个直观的定义是,该文法可以用BNF来完整的表达。可查看http://en.wikipedia.org/wiki/Context-free_grammar

    解析器类型 Types of parsers

    有两种基本的解析器——自顶向下解析及自底向上解析。比较直观的解释是,自顶向下解析,查看语法的最高层结构并试着匹配其中一个;自底向上解析则从输入开始,逐步将其转换为语法规则,从底层规则开始直到匹配高层规则。

    来看一下这两种解析器如何解析上面的例子:

    自顶向下解析器从最高层规则开始——它先识别出“2+3“,将其视为一个表达式,然后识别出”2+3-1“为一个表达式(识别表达式的过程中匹配了其他规则,但出发点是最高层规则)。

    自底向上解析会扫描输入直到匹配了一条规则,然后用该规则取代匹配的输入,直到解析完所有输入。部分匹配的表达式被放置在解析堆栈中。

    Stack

    Input

      2 + 3 – 1
    term + 3 – 1
    term operation 3 – 1
    expression – 1
    expression operation 1
    expression  

    自底向上解析器称为shift reduce 解析器,因为输入向右移动(想象一个指针首先指向输入开始处,并向右移动),并逐渐简化为语法规则。

    自动化解析 Generating parse

    解析器生成器这个工具可以自动生成解析器,只需要指定语言的文法——词汇表及语法规则,它就可以生成一个解析器。创建一个解析器需要对解析有深入的理解,而且手动的创建一个由较好性能的解析器并不容易,所以解析生成器很有用。Webkit使用两个知名的解析生成器——用于创建语法分析器的Flex及创建解析器的Bison(你可能接触过Lex和Yacc)。Flex的输入是一个包含了符号定义的正则表达式,Bison的输入是用BNF格式表示的语法规则。rs automatically

    HTML解析器 HTML Parser

    HTML解析器的工作是将html标识解析为解析树。

    HTML文法定义 The HTML grammar definition

    W3C组织制定规范定义了HTML的词汇表和语法。

    非上下文无关文法 Not a context free grammar

    正如在解析简介中提到的,上下文无关文法的语法可以用类似BNF的格式来定义。

    不幸的是,所有的传统解析方式都不适用于html(当然我提出它们并不只是因为好玩,它们将用来解析css和js),html不能简单的用解析所需的上下文无关文法来定义。

    Html 有一个正式的格式定义——DTD(Document Type Definition 文档类型定义)——但它并不是上下文无关文法,html更接近于xml,现在有很多可用的xml解析器,html有个xml的变体——xhtml,它们间的不同在于,html更宽容,它允许忽略一些特定标签,有时可以省略开始或结束标签。总的来说,它是一种soft语法,不像xml呆板、固执。

    显然,这个看起来很小的差异却带来了很大的不同。一方面,这是html流行的原因——它的宽容使web开发人员的工作更加轻松,但另一方面,这也使很难去写一个格式化的文法。所以,html的解析并不简单,它既不能用传统的解析器解析,也不能用xml解析器解析。

    HTML DTD

    Html适用DTD格式进行定义,这一格式是用于定义SGML家族的语言,包括了对所有允许元素及它们的属性和层次关系的定义。正如前面提到的,html DTD并没有生成一种上下文无关文法。

    DTD有一些变种,标准模式只遵守规范,而其他模式则包含了对浏览器过去所使用标签的支持,这么做是为了兼容以前内容。最新的标准DTD在http://www.w3.org/TR/html4/strict.dtd

    DOM

    输出的树,也就是解析树,是由DOM元素及属性节点组成的。DOM是文档对象模型的缩写,它是html文档的对象表示,作为html元素的外部接口供js等调用。

    树的根是“document”对象。

    DOM和标签基本是一一对应的关系,例如,如下的标签:

     

    将会被转换为下面的DOM树:

    现代浏览器的工作原理

    图8:示例标签对应的DOM树

    和html一样,DOM的规范也是由W3C组织制定的。访问http://www.w3.org/DOM/DOMTR,这是使用文档的一般规范。一个模型描述一种特定的html元素,可以在http://www.w3.org/TR/2003/REC-DOM-Level-2-HTML-20030109/idl-definitions.htm 查看html定义。

    这里所谓的树包含了DOM节点是说树是由实现了DOM接口的元素构建而成的,浏览器使用已被浏览器内部使用的其他属性的具体实现。

    解析算法 The parsing algorithm

    正如前面章节中讨论的,hmtl不能被一般的自顶向下或自底向上的解析器所解析。

    原因是:

    1. 这门语言本身的宽容特性

    2. 浏览器对一些常见的非法html有容错机制

    3. 解析过程是往复的,通常源码不会在解析过程中发生改变,但在html中,脚本标签包含的“document.write ”可能添加标签,这说明在解析过程中实际上修改了输入

    不能使用正则解析技术,浏览器为html定制了专属的解析器。

    Html5规范中描述了这个解析算法,算法包括两个阶段——符号化及构建树。

    符号化是词法分析的过程,将输入解析为符号,html的符号包括开始标签、结束标签、属性名及属性值。

    符号识别器识别出符号后,将其传递给树构建器,并读取下一个字符,以识别下一个符号,这样直到处理完所有输入。

    现代浏览器的工作原理

    图9:HTML解析流程

    符号识别算法 The tokenization algorithm

    算法输出html符号,该算法用状态机表示。每次读取输入流中的一个或多个字符,并根据这些字符转移到下一个状态,当前的符号状态及构建树状态共同影响结果,这意味着,读取同样的字符,可能因为当前状态的不同,得到不同的结果以进入下一个正确的状态。

    这个算法很复杂,这里用一个简单的例子来解释这个原理。

    基本示例——符号化下面的html:

     

    初始状态为“Data State”,当遇到“<”字符,状态变为“Tag open state”,读取一个a-z的字符将产生一个开始标签符号,状态相应变为“Tag name state”,一直保持这个状态直到读取到“>”,每个字符都附加到这个符号名上,例子中创建的是一个html符号。

    当读取到“>”,当前的符号就完成了,此时,状态回到“Data state”,“<body>”重复这一处理过程。到这里,html和body标签都识别出来了。现在,回到“Data state”,读取“Hello world”中的字符“H”将创建并识别出一个字符符号,这里会为“Hello world”中的每个字符生成一个字符符号。

    这样直到遇到“</body>”中的“<”。现在,又回到了“Tag open state”,读取下一个字符“/”将创建一个闭合标签符号,并且状态转移到“Tag name state”,还是保持这一状态,直到遇到“>”。然后,产生一个新的标签符号并回到“Data state”。后面的“</html>”将和“</body>”一样处理。

    现代浏览器的工作原理

    图10:符号化示例输入

    树的构建算法 Tree construction algorithm

    在树的构建阶段,将修改以Document为根的DOM树,将元素附加到树上。每个由符号识别器识别生成的节点将会被树构造器进行处理,规范中定义了每个符号相对应的Dom元素,对应的Dom元素将会被创建。这些元素除了会被添加到Dom树上,还将被添加到开放元素堆栈中。这个堆栈用来纠正嵌套的未匹配和未闭合标签,这个算法也是用状态机来描述,所有的状态采用插入模式。

    来看一下示例中树的创建过程:

     

    构建树这一阶段的输入是符号识别阶段生成的符号序列。

    首先是“initial mode”,接收到html符号后将转换为“before html”模式,在这个模式中对这个符号进行再处理。此时,创建了一个HTMLHtmlElement元素,并将其附加到根Document对象上。

    状态此时变为“before head”,接收到body符号时,即使这里没有head符号,也将自动创建一个HTMLHeadElement元素并附加到树上。

    现在,转到“in head”模式,然后是“after head”。到这里,body符号会被再次处理,将创建一个HTMLBodyElement并插入到树中,同时,转移到“in body”模式。

    然后,接收到字符串“Hello world”的字符符号,第一个字符将导致创建并插入一个text节点,其他字符将附加到该节点。

    接收到body结束符号时,转移到“after body”模式,接着接收到html结束符号,这个符号意味着转移到了“after after body”模式,当接收到文件结束符时,整个解析过程结束。

    现代浏览器的工作原理

    图11:示例html树的构建过程

    解析结束时的处理 Action when the parsing is finished

    在这个阶段,浏览器将文档标记为可交互的,并开始解析处于延时模式中的脚本——这些脚本在文档解析后执行。

    文档状态将被设置为完成,同时触发一个load事件。

    Html5规范中有符号化及构建树的完整算法(http://www.w3.org/TR/html5/syntax.html#html-parser)。

    浏览器容错 Browsers error tolerance

    你从来不会在一个html页面上看到“无效语法”这样的错误,浏览器修复了无效内容并继续工作。

    以下面这段html为例:

     

    这段html违反了很多规则(mytag不是合法的标签,p及div错误的嵌套等等),但是浏览器仍然可以没有任何怨言的继续显示,它在解析的过程中修复了html作者的错误。

    浏览器都具有错误处理的能力,但是,另人惊讶的是,这并不是html最新规范的内容,就像书签及前进后退按钮一样,它只是浏览器长期发展的结果。一些比较知名的非法html结构,在许多站点中出现过,浏览器都试着以一种和其他浏览器一致的方式去修复。

    Html5规范定义了这方面的需求,webkit在html解析类开始部分的注释中做了很好的总结。

    解析器将符号化的输入解析为文档并创建文档,但不幸的是,我们必须处理很多没有很好格式化的html文档,至少要小心下面几种错误情况。

    1. 在未闭合的标签中添加明确禁止的元素。这种情况下,应该先将前一标签闭合

    2. 不能直接添加元素。有些人在写文档的时候会忘了中间一些标签(或者中间标签是可选的),比如HTML HEAD BODY TR TD LI等

    3. 想在一个行内元素中添加块状元素。关闭所有的行内元素,直到下一个更高的块状元素

    4. 如果这些都不行,就闭合当前标签直到可以添加该元素。

    下面来看一些webkit容错的例子:

    一些网站使用</br>替代<br>,为了兼容IE和Firefox,webkit将其看作<br>。

    代码:

     

    Note-这里的错误处理在内部进行,用户看不到。

    迷路的表格

    这指一个表格嵌套在另一个表格中,但不在它的某个单元格内。

    比如下面这个例子:

     

    webkit将会将嵌套的表格变为两个兄弟表格:

     

    代码:

     

    webkit使用堆栈存放当前的元素内容,它将从外部表格的堆栈中弹出内部的表格,则它们变为了兄弟表格。

    嵌套的表单元素

    用户将一个表单嵌套到另一个表单中,则第二个表单将被忽略。

    代码:

     

    太深的标签继承

    www.liceo.edu.mx是一个由嵌套层次的站点的例子,最多只允许20个相同类型的标签嵌套,多出来的将被忽略。

    代码:

     

    放错了地方的html、body闭合标签

    又一次不言自明。

    支持不完整的html。我们从来不闭合body,因为一些愚蠢的网页总是在还未真正结束时就闭合它。我们依赖调用end方法去执行关闭的处理。

    代码:

     

    所以,web开发者要小心了,除非你想成为webkit容错代码的范例,否则还是写格式良好的html吧。

    CSS解析 CSS parsing

    还记得简介中提到的解析的概念吗,不同于html,css属于上下文无关文法,可以用前面所描述的解析器来解析。Css规范定义了css的词法及语法文法。

    看一些例子:

    每个符号都由正则表达式定义了词法文法(词汇表):

     

    “ident”是识别器的缩写,相当于一个class名,“name”是一个元素id(用“#”引用)。

    语法用BNF进行描述:

     

    说明:一个规则集合有这样的结构

     

    div.error和a.error时选择器,大括号中的内容包含了这条规则集合中的规则,这个结构在下面的定义中正式的定义了:

     

    这说明,一个规则集合具有一个或是可选个数的多个选择器,这些选择器以逗号和空格(S表示空格)进行分隔。每个规则集合包含大括号及大括号中的一条或多条以分号隔开的声明。声明和选择器在后面进行定义。

    Webkit CSS 解析器 Webkit CSS parser

    Webkit使用Flex和Bison解析生成器从CSS语法文件中自动生成解析器。回忆一下解析器的介绍,Bison创建一个自底向上的解析器,Firefox使用自顶向下解析器。它们都是将每个css文件解析为样式表对象,每个对象包含css规则,css规则对象包含选择器和声明对象,以及其他一些符合css语法的对象。

    现代浏览器的工作原理

    图12:解析css

    脚本解析 Parsing scripts

    本章将介绍Javascript。

    处理脚本及样式表的顺序 The order of processing scripts and style sheets

    脚本

    web的模式是同步的,开发者希望解析到一个script标签时立即解析执行脚本,并阻塞文档的解析直到脚本执行完。如果脚本是外引的,则网络必须先请求到这个资源——这个过程也是同步的,会阻塞文档的解析直到资源被请求到。这个模式保持了很多年,并且在html4及html5中都特别指定了。开发者可以将脚本标识为defer,以使其不阻塞文档解析,并在文档解析结束后执行。Html5增加了标记脚本为异步的选项,以使脚本的解析执行使用另一个线程。

    预解析 Speculative parsing

    Webkit和Firefox都做了这个优化,当执行脚本时,另一个线程解析剩下的文档,并加载后面需要通过网络加载的资源。这种方式可以使资源并行加载从而使整体速度更快。需要注意的是,预解析并不改变Dom树,它将这个工作留给主解析过程,自己只解析外部资源的引用,比如外部脚本、样式表及图片。

    样式表 Style sheets

    样式表采用另一种不同的模式。理论上,既然样式表不改变Dom树,也就没有必要停下文档的解析等待它们,然而,存在一个问题,脚本可能在文档的解析过程中请求样式信息,如果样式还没有加载和解析,脚本将得到错误的值,显然这将会导致很多问题,这看起来是个边缘情况,但确实很常见。Firefox在存在样式表还在加载和解析时阻塞所有的脚本,而chrome只在当脚本试图访问某些可能被未加载的样式表所影响的特定的样式属性时才阻塞这些脚本。

    渲染树的构造 Render tree construction

    当Dom树构建完成时,浏览器开始构建另一棵树——渲染树。渲染树由元素显示序列中的可见元素组成,它是文档的可视化表示,构建这棵树是为了以正确的顺序绘制文档内容。

    Firefox将渲染树中的元素称为frames,webkit则用renderer或渲染对象来描述这些元素。

    一个渲染对象直到怎么布局及绘制自己及它的children。

    RenderObject是Webkit的渲染对象基类,它的定义如下:

     

    每个渲染对象用一个和该节点的css盒模型相对应的矩形区域来表示,正如css2所描述的那样,它包含诸如宽、高和位置之类的几何信息。盒模型的类型受该节点相关的display样式属性的影响(参考样式计算章节)。下面的webkit代码说明了如何根据display属性决定某个节点创建何种类型的渲染对象。

     

    元素的类型也需要考虑,例如,表单控件和表格带有特殊的框架。

    在webkit中,如果一个元素想创建一个特殊的渲染对象,它需要复写“createRenderer”方法,使渲染对象指向不包含几何信息的样式对象。

    渲染树和Dom树的关系 The render tree relation to the DOM tree

    渲染对象和Dom元素相对应,但这种对应关系不是一对一的,不可见的Dom元素不会被插入渲染树,例如head元素。另外,display属性为none的元素也不会在渲染树中出现(visibility属性为hidden的元素将出现在渲染树中)。

    还有一些Dom元素对应几个可见对象,它们一般是一些具有复杂结构的元素,无法用一个矩形来描述。例如,select元素有三个渲染对象——一个显示区域、一个下拉列表及一个按钮。同样,当文本因为宽度不够而折行时,新行将作为额外的渲染元素被添加。另一个多个渲染对象的例子是不规范的html,根据css规范,一个行内元素只能仅包含行内元素或仅包含块状元素,在存在混合内容时,将会创建匿名的块状渲染对象包裹住行内元素。

    一些渲染对象和所对应的Dom节点不在树上相同的位置,例如,浮动和绝对定位的元素在文本流之外,在两棵树上的位置不同,渲染树上标识出真实的结构,并用一个占位结构标识出它们原来的位置。

     现代浏览器的工作原理

    图12:渲染树及对应的Dom树

    创建树的流程 The flow of constructing the tree

    Firefox中,表述为一个监听Dom更新的监听器,将frame的创建委派给Frame Constructor,这个构建器计算样式(参看样式计算)并创建一个frame。

    Webkit中,计算样式并生成渲染对象的过程称为attachment,每个Dom节点有一个attach方法,attachment的过程是同步的,调用新节点的attach方法将节点插入到Dom树中。

    处理html和body标签将构建渲染树的根,这个根渲染对象对应被css规范称为containing block的元素——包含了其他所有块元素的顶级块元素。它的大小就是viewport——浏览器窗口的显示区域,Firefox称它为viewPortFrame,webkit称为RenderView,这个就是文档所指向的渲染对象,树中其他的部分都将作为一个插入的Dom节点被创建。

    样式计算 Style Computation

    创建渲染树需要计算出每个渲染对象的可视属性,这可以通过计算每个元素的样式属性得到。

    样式包括各种来源的样式表,行内样式元素及html中的可视化属性(例如bgcolor),可视化属性转化为css样式属性。

    样式表来源于浏览器默认样式表,及页面作者和用户提供的样式表——有些样式是浏览器用户提供的(浏览器允许用户定义喜欢的样式,例如,在Firefox中,可以通过在Firefox Profile目录下放置样式表实现)。

    计算样式的一些困难:

    1. 样式数据是非常大的结构,保存大量的样式属性会带来内存问题

    2. 如果不进行优化,找到每个元素匹配的规则会导致性能问题,为每个元素查找匹配的规则都需要遍历整个规则表,这个过程有很大的工作量。选择符可能有复杂的结构,匹配过程如果沿着一条开始看似正确,后来却被证明是无用的路径,则必须去尝试另一条路径。

    例如,下面这个复杂选择符

    这意味着规则应用到三个div的后代div元素,选择树上一条特定的路径去检查,这可能需要遍历节点树,最后却发现它只是两个div的后代,并不使用该规则,然后则需要沿着另一条路径去尝试

    3. 应用规则涉及非常复杂的级联,它们定义了规则的层次

    我们来看一下浏览器如何处理这些问题:

    共享样式数据

    webkit节点引用样式对象(渲染样式),某些情况下,这些对象可以被节点间共享,这些节点需要是兄弟或是表兄弟节点,并且:

    • ▲这些元素必须处于相同的鼠标状态(比如不能一个处于hover,而另一个不是)
    • ▲不能有元素具有id
    • ▲标签名必须匹配
    • ▲class属性必须匹配
    • ▲对应的属性必须相同
    • ▲链接状态必须匹配
    • ▲焦点状态必须匹配
    • ▲不能有元素被属性选择器影响
    • ▲元素不能有行内样式属性
    • ▲不能有生效的兄弟选择器,webcore在任何兄弟选择器相遇时只是简单的抛出一个全局转换,并且在它们显示时使整个文档的样式共享失效,这些包括+选择器和类似:first-child和:last-child这样的选择器。

    Firefox规则树 Firefox rule tree

    Firefox用两个树用来简化样式计算-规则树和样式上下文树,webkit也有样式对象,但它们并没有存储在类似样式上下文树这样的树中,只是由Dom节点指向其相关的样式。

    现代浏览器的工作原理

    图14:Firefox样式上下文树

    样式上下文包含最终值,这些值是通过以正确顺序应用所有匹配的规则,并将它们由逻辑值转换为具体的值,例如,如果逻辑值为屏幕的百分比,则通过计算将其转化为绝对单位。样式树的使用确实很巧妙,它使得在节点中共享的这些值不需要被多次计算,同时也节省了存储空间。

    所有匹配的规则都存储在规则树中,一条路径中的底层节点拥有最高的优先级,这棵树包含了所找到的 所有规则匹配的路径(译注:可以取巧理解为每条路径对应一个节点,路径上包含了该节点所匹配的所有规则)。规则树并不是一开始就为所有节点进行计算,而是 在某个节点需要计算样式时,才进行相应的计算并将计算后的路径添加到树中。

    我们将树上的路径看成辞典中的单词,假如已经计算出了如下的规则树:

    现代浏览器的工作原理

    假如需要为内容树中的另一个节点匹配规则,现在知道匹配的规则(以正确的顺序)为B-E-I,因为我们已经计算出了路径A-B-E-I-L,所以树上已经存在了这条路径,剩下的工作就很少了。

    现在来看一下树如何保存。

    结构化

    样式上下文按结构划分,这些结构包括类似border或color这样的特定分类的样式信息。一个结构中的所有特性不是继承的就是非继承的,对继承的特性,除非元素自身有定义,否则就从它的parent继承。非继承的特性(称为reset特性)如果没有定义,则使用默认的值。

    样式上下文树缓存完整的结构(包括计算后的值),这样,如果底层节点没有为一个结构提供定义,则使用上层节点缓存的结构。

    使用规则树计算样式上下文

    当为一个特定的元素计算样式时,首先计算出规则树中的一条路径,或是使用已经存在的一条,然后使 用路径中的规则去填充新的样式上下文,从样式的底层节点开始,它具有最高优先级(通常是最特定的选择器),遍历规则树,直到填满结构。如果在那个规则节点 没有定义所需的结构规则,则沿着路径向上,直到找到该结构规则。

    如果最终没有找到该结构的任何规则定义,那么如果这个结构是继承型的,则找到其在内容树中的parent的结构,这种情况下,我们也成功的共享了结构;如果这个结构是reset型的,则使用默认的值。

    如果特定的节点添加了值,那么需要做一些额外的计算以将其转换为实际值,然后在树上的节点缓存该值,使它的children可以使用。

    当一个元素和它的一个兄弟元素指向同一个树节点时,完整的样式上下文可以被它们共享。

    来看一个例子:假设有下面这段html

     

    以及下面这些规则

     

    简化下问题,我们只填充两个结构——color和margin,color结构只包含一个成员-颜色,margin结构包含四边。

    生成的规则树如下(节点名:指向的规则)

    现代浏览器的工作原理

    上下文树如下(节点名:指向的规则节点)

    现代浏览器的工作原理

    假设我们解析html,遇到第二个div标签,我们需要为这个节点创建样式上下文,并填充它的样式结构。

    我们进行规则匹配,找到这个div匹配的规则为1、2、6,我们发现规则树上已经存在了一条我们可以使用的路径1、2,我们只需为规则6新增一个节点添加到下面(就是规则树中的F)。

    然后创建一个样式上下文并将其放到上下文树中,新的样式上下文将指向规则树中的节点F。

    现在我们需要填充这个样式上下文,先从填充margin结构开始,既然最后一个规则节点没有添加margin结构,沿着路径向上,直到找到缓存的前面插入节点计算出的结构,我们发现B是最近的指定margin值的节点。因为已经有了color结构的定义,所以不能使用缓存的结构,既然color只有一个属性,也就不需要沿着路径向上填充其他属性。计算出最终值(将字符串转换为RGB等),并缓存计算后的结构。

    第二个span元素更简单,进行规则匹配后发现它指向规则G,和前一个span一样,既然有兄弟节点指向同一个节点,就可以共享完整的样式上下文,只需指向前一个span的上下文。

    因为结构中包含继承自parent的规则,上下文树做了缓存(color特性是继承来的,但Firefox将其视为reset并在规则树中缓存)。

    例如,如果我们为一个paragraph的文字添加规则:

    p {font-family:Verdana;font size:10px;font-weight:bold}

    那么这个p在内容树中的子节点div,会共享和它parent一样的font结构,这种情况发生在没有为这个div指定font规则时。

    Webkit中,并没有规则树,匹配的声明会被遍历四次,先是应用非important的高优先级属性(之所以先应用这些属性,是因为其他的依赖于它们-比如display),其次是高优先级important的,接着是一般优先级非important的,最后是一般优先级important的规则。这样,出现多次的属性将被按照正确的级联顺序进行处理,最后一个生效。

    总结一下,共享样式对象(结构中完整或部分内容)解决了问题1和3,Firefox的规则树帮助以正确的顺序应用规则。

    对规则进行处理以简化匹配过程

    样式规则有几个来源:

    · 外部样式表或style标签内的css规则

    · 行内样式属性

    · html可视化属性(映射为相应的样式规则)

    后面两个很容易匹配到元素,因为它们所拥有的样式属性和html属性可以将元素作为key进行映射。

    就像前面问题2所提到的,css的规则匹配可能很狡猾,为了解决这个问题,可以先对规则进行处理,以使其更容易被访问。

    解析完样式表之后,规则会根据选择符添加一些hash映射,映射可以是根据id、class、标签名或是任何不属于这些分类的综合映射。如果选择符为id,规则将被添加到id映射,如果是class,则被添加到class映射,等等。

    这个处理是匹配规则更容易,不需要查看每个声明,我们能从映射中找到一个元素的相关规则,这个优化使在进行规则匹配时减少了95+%的工作量。

    来看下面的样式规则:

    p.error {color:red}

    #messageDiv {height:50px}

    div {margin:5px}

    第一条规则将被插入class映射,第二条插入id映射,第三条是标签映射。

    下面这个html片段:

    我们首先找到p元素对应的规则,class映射将包含一个“error”的key,找到p.error的规则,div在id映射和标签映射中都有相关的规则,剩下的工作就是找出这些由key对应的规则中哪些确实是正确匹配的。

    例如,如果div的规则是

    这也是标签映射产生的,因为key是最右边的选择符,但它并不匹配这里的div元素,因为这里的div没有table祖先。

    Webkit和Firefox都会做这个处理。

    以正确的级联顺序应用规则

    样式对象拥有对应所有可见属性的属性,如果特性没有被任何匹配的规则所定义,那么一些特性可以从parent的样式对象中继承,另外一些使用默认值。

    这个问题的产生是因为存在不止一处的定义,这里用级联顺序解决这个问题。

    样式表的级联顺序

    一个样式属性的声明可能在几个样式表中出现,或是在一个样式表中出现多次,因此,应用规则的顺序至关重要,这个顺序就是级联顺序。根据css2的规范,级联顺序为(从低到高):

    • 1. 浏览器声明
    • 2. 用户声明
    • 3. 作者的一般声明
    • 4. 作者的important声明
    • 5. 用户important声明

    浏览器声明是最不重要的,用户只有在声明被标记为important时才会覆盖作者的声明。具有同等级别的声明将根据specifity以及它们被定义时的顺序进行排序。Html可视化属性将被转换为匹配的css声明,它们被视为最低优先级的作者规则。

    Specifity

    Css2规范中定义的选择符specifity如下:

    • · 如果声明来自style属性,而不是一个选择器的规则,则计1,否则计0(=a)
    • · 计算选择器中id属性的数量(=b)
    • · 计算选择器中class及伪类的数量(=c)
    • · 计算选择器中元素名及伪元素的数量(=d)

    连接a-b-c-d四个数量(用一个大基数的计算系统)将得到specifity。这里使用的基数由分类中最高的基数定义。例如,如果a为14,可以使用16进制。不同情况下,a为17时,则需要使用阿拉伯数字17作为基数,这种情况可能在这个选择符时发生html body div div …(选择符中有17个标签,一般不太可能)。

    一些例子:

     

    规则排序

    规则匹配后,需要根据级联顺序对规则进行排序,webkit先将小列表用冒泡排序,再将它们合并为一个大列表,webkit通过为规则复写“>”操作来执行排序:

     

    逐步处理 Gradual process

    webkit使用一个标志位标识所有顶层样式表都已加载,如果在attch时样式没有完全加载,则放置占位符,并在文档中标记,一旦样式表完成加载就重新进行计算。

    布局 Layout

    当渲染对象被创建并添加到树中,它们并没有位置和大小,计算这些值的过程称为layout或reflow。

    Html使用基于流的布局模型,意味着大部分时间,可以以单一的途径进行几何计算。流中靠后的元素并不会影响前面元素的几何特性,所以布局可以在文档中从右向左、自上而下的进行。也存在一些例外,比如html tables。

    坐标系统相对于根frame,使用top和left坐标。

    布局是一个递归的过程,由根渲染对象开始,它对应html文档元素,布局继续递归的通过一些或所有的frame层级,为每个需要几何信息的渲染对象进行计算。

    根渲染对象的位置是0,0,它的大小是viewport-浏览器窗口的可见部分。

    所有的渲染对象都有一个layout或reflow方法,每个渲染对象调用需要布局的children的layout方法。

    Dirty bit 系统

    为了不因为每个小变化都全部重新布局,浏览器使用一个dirty bit系统,一个渲染对象发生了变化或是被添加了,就标记它及它的children为dirty-需要layout。存在两个标识-dirty及children are dirty,children are dirty说明即使这个渲染对象可能没问题,但它至少有一个child需要layout。

    全局和增量 layout

    当layout在整棵渲染树触发时,称为全局layout,这可能在下面这些情况下发生:

    1. 一个全局的样式改变影响所有的渲染对象,比如字号的改变

    2. 窗口resize

    layout也可以是增量的,这样只有标志为dirty的渲染对象会重新布局(也将导致一些额外的布局)。增量 layout会在渲染对象dirty时异步触发,例如,当网络接收到新的内容并添加到Dom树后,新的渲染对象会添加到渲染树中。

    现代浏览器的工作原理

    图20:增量 layout

    异步和同步layout

    增量layout的过程是异步的,Firefox为增量layout生成了reflow队列,以及一个调度执行这些批处理命令。Webkit也有一个计时器用来执行增量layout-遍历树,为dirty状态的渲染对象重新布局。

    另外,当脚本请求样式信息时,例如“offsetHeight”,会同步的触发增量布局。

    全局的layout一般都是同步触发。

    有些时候,layout会被作为一个初始layout之后的回调,比如滑动条的滑动。

    优化

    当一个layout因为resize或是渲染位置改变(并不是大小改变)而触发时,渲染对象的大小将会从缓存中读取,而不会重新计算。

    一般情况下,如果只有子树发生改变,则layout并不从根开始。这种情况发生在,变化发生在元素自身并且不影响它周围元素,例如,将文本插入文本域(否则,每次击键都将触发从根开始的重排)。

    layout过程

    layout一般有下面这几个部分:

    1. parent渲染对象决定它的宽度

    2. parent渲染对象读取chilidren,并:

    1. 放置child渲染对象(设置它的x和y)

    2. 在需要时(它们当前为dirty或是处于全局layout或者其他原因)调用child渲染对象的layout,这将计算child的高度

    3. parent渲染对象使用child渲染对象的累积高度,以及margin和padding的高度来设置自己的高度-这将被parent渲染对象的parent使用

    4. 将dirty标识设置为false

    Firefox使用一个“state”对象(nsHTMLReflowState)做为参数去布局(firefox称为reflow),state包含parent的宽度及其他内容。

    Firefox布局的输出是一个“metrics”对象(nsHTMLReflowMetrics)。它包括渲染对象计算出的高度。

    宽度计算

    渲染对象的宽度使用容器的宽度、渲染对象样式中的宽度及margin、border进行计算。例如,下面这个div的宽度:

    webkit中宽度的计算过程是(RenderBox类的calcWidth方法):

    · 容器的宽度是容器的可用宽度和0中的最大值,这里的可用宽度为:contentWidth=clientWidth()-paddingLeft()-paddingRight(),clientWidth和clientHeight代表一个对象内部的不包括border和滑动条的大小

    · 元素的宽度指样式属性width的值,它可以通过计算容器的百分比得到一个绝对值

    · 加上水平方向上的border和padding

    到这里是最佳宽度的计算过程,现在计算宽度的最大值和最小值,如果最佳宽度大于最大宽度则使用最大宽度,如果小于最小宽度则使用最小宽度。最后缓存这个值,当需要layout但宽度未改变时使用。

    Line breaking

    当一个渲染对象在布局过程中需要折行时,则暂停并告诉它的parent它需要折行,parent将创建额外的渲染对象并调用它们的layout。

    绘制 Painting

    绘制阶段,遍历渲染树并调用渲染对象的paint方法将它们的内容显示在屏幕上,绘制使用UI基础组件,这在UI的章节有更多的介绍。

    全局和增量

    和布局一样,绘制也可以是全局的-绘制完整的树-或增量的。在增量的绘制过程中,一些渲染对象以不影响整棵树的方式改变,改变的渲染对象使其在屏幕上的矩形区域失效,这将导致操作系统将其看作dirty区域,并产生一个paint事件,操作系统很巧妙的处理这个过程,并将多个区域合并为一个。Chrome中,这个过程更复杂些,因为渲染对象在不同的进程中,而不是在主进程中。Chrome在一定程度上模拟操作系统的行为,表现为监听事件并派发消息给渲染根,在树中查找到相关的渲染对象,重绘这个对象(往往还包括它的children)。

    绘制顺序

    css2定义了绘制过程的顺序-http://www.w3.org/TR/CSS21/zindex.html。这个就是元素压入堆栈的顺序,这个顺序影响着绘制,堆栈从后向前进行绘制。

    一个块渲染对象的堆栈顺序是:

    • 1. 背景色
    • 2. 背景图
    • 3. border
    • 4. children
    • 5. outline

    Firefox显示列表

    Firefox读取渲染树并为绘制的矩形创建一个显示列表,该列表以正确的绘制顺序包含这个矩形相关的渲染对象。

    用这样的方法,可以使重绘时只需查找一次树,而不需要多次查找——绘制所有的背景、所有的图片、所有的border等等。

    Firefox优化了这个过程,它不添加会被隐藏的元素,比如元素完全在其他不透明元素下面。

    Webkit矩形存储

    重绘前,webkit将旧的矩形保存为位图,然后只绘制新旧矩形的差集。

    动态变化

    浏览器总是试着以最小的动作响应一个变化,所以一个元素颜色的变化将只导致该元素的重绘,元素位置的变化将大致元素的布局和重绘,添加一个Dom节点,也会大致这个元素的布局和重绘。一些主要的变化,比如增加html元素的字号,将会导致缓存失效,从而引起整数的布局和重绘。

    渲染引擎的线程

    渲染引擎是单线程的,除了网络操作以外,几乎所有的事情都在单一的线程中处理,在Firefox和Safari中,这是浏览器的主线程,Chrome中这是tab的主线程。

    网络操作由几个并行线程执行,并行连接的个数是受限的(通常是2-6个)。

    事件循环

    浏览器主线程是一个事件循环,它被设计为无限循环以保持执行过程的可用,等待事件(例如layout和paint事件)并执行它们。下面是Firefox的主要事件循环代码。

     

    CSS2 可视模型 CSS2 visual module

    画布 The Canvas

    根据CSS2规范,术语canvas用来描述格式化的结构所渲染的空间——浏览器绘制内容的地方。画布对每个维度空间都是无限大的,但浏览器基于viewport的大小选择了一个初始宽度。

    根据http://www.w3.org/TR/CSS2/zindex.html的定义,画布如果是包含在其他画布内则是透明的,否则浏览器会指定一个颜色。

    CSS盒模型

    CSS盒模型描述了矩形盒,这些矩形盒是为文档树中的元素生成的,并根据可视的格式化模型进行布局。每个box包括内容区域(如图片、文本等)及可选的四周padding、border和margin区域。

    现代浏览器的工作原理

    每个节点生成0-n个这样的box。

    所有的元素都有一个display属性,用来决定它们生成box的类型,例如:

    block-生成块状box

    inline-生成一个或多个行内box

    none-不生成box

    默认的是inline,但浏览器样式表设置了其他默认值,例如,div元素默认为block。可以访问http://www.w3.org/TR/CSS2/sample.html查看更多的默认样式表示例。

    定位策略 Position scheme

    这里有三种策略:

    1. normal-对象根据它在文档的中位置定位,这意味着它在渲染树和在Dom树中位置一致,并根据它的盒模型和大小进行布局

    2. float-对象先像普通流一样布局,然后尽可能的向左或是向右移动

    3. absolute-对象在渲染树中的位置和Dom树中位置无关

    static和relative是normal,absolute和fixed属于absolute。

    在static定位中,不定义位置而使用默认的位置。其他策略中,作者指定位置——top、bottom、left、right。

    Box布局的方式由这几项决定:box的类型、box的大小、定位策略及扩展信息(比如图片大小和屏幕尺寸)。

    Box类型

    Block box:构成一个块,即在浏览器窗口上有自己的矩形

    现代浏览器的工作原理

    Inline box:并没有自己的块状区域,但包含在一个块状区域内

    现代浏览器的工作原理

    block一个挨着一个垂直格式化,inline则在水平方向上格式化。

    现代浏览器的工作原理

    Inline盒模型放置在行内或是line box中,每行至少和最高的box一样高,当box以baseline对齐时——即一个元素的底部和另一个box上除底部以外的某点对齐,行高可以比最高的box高。当容器宽度不够时,行内元素将被放到多行中,这在一个p元素中经常发生。

    现代浏览器的工作原理

    定位 Position

    Relative

    相对定位——先按照一般的定位,然后按所要求的差值移动。

    现代浏览器的工作原理

    Floats

    一个浮动的box移动到一行的最左边或是最右边,其余的box围绕在它周围。下面这段html:

     

    将显示为:

    现代浏览器的工作原理

    Absolute和Fixed

    这种情况下的布局完全不顾普通的文档流,元素不属于文档流的一部分,大小取决于容器。Fixed时,容器为viewport(可视区域)。

    现代浏览器的工作原理

    图17:fixed

    注意-fixed即使在文档流滚动时也不会移动。

    Layered representation

    这个由CSS属性中的z-index指定,表示盒模型的第三个大小,即在z轴上的位置。Box分发到堆栈中(称为堆栈上下文),每个堆栈中靠后的元素将被较早绘制,栈顶靠前的元素离用户最近,当发生交叠时,将隐藏靠后的元素。堆栈根据z-index属性排序,拥有z-index属性的box形成了一个局部堆栈,viewport有外部堆栈,例如: