计算机网络:自顶向下
工具
wireshark:分组嗅探器、抓包。
best Trace:路由跟踪
nmap:侦察TCP、UDP打开端口、防火墙机器配置、甚至是应用程序的版本和操作系统。
概述:
第一章:简介,宏观描述Internet的产生、节点及硬件、节点间的交互方式,边缘客户(端系统)接入因特网的方式,ISP网络服务提供商的层级结构等。
第二章到第六章:为从上到下讲解五层计算机网络体系的五个层次:应用层、运输层、网络层(IP层)、链路层、物理层。(第二、三章,为网络边缘,即端系统上的协议。四、五、六章为网络核心协议)
第七章到第九章:无线和移动网络、计算机网络安全、多媒体网络。
我是从第二章开始记录。
第二章 应用层
2.1网络应用程序体系结构
应用程序体系结构:
①客户-服务器结构:一个总是打开的服务器,服务于来自许多主机(上的进程)的请求。
②P2P结构(peer-to-peer,peer:对等、同龄人):对等方到对等方结构,对专用服务器几乎甚至没有依赖。
③混合两者的结构。如迅雷的看看。
供应用程序使用的运输服务:
要求:
一般应用程序使用运输层服务时,考虑四个方面:可靠数据传输、吞吐量、定时、安全性。
可靠数据传输:保证数据能完整、无误、按顺序地传送到接收方。
吞吐量:是否能提供有下限的吞吐量数值。与一条网络路径上的最慢链路的速率相关。多用于带宽敏感的应用(bandwidth-sensitive application),如:多媒体、语音通话等。
定时:也可以说延迟,发送方注入套接字的每个比特,是否能在规定时间内到达接收方,如100ms内。多用于:网络游戏、线上VR等实时网络应用。非实时的,当然也希望延迟越低越好,但是没有约束。
安全性:进程注入套接字的数据,是否与运输链路上的数据一样?如果一样,则没有进行加密。如SSL(安全套接字层)协议,是对TCP的拓展,对数据会进行加密和解密操作,以保证安全性。
Internet提供的运输服务
1:TCP(Transmission Control Protocol,传输控制协议)
面向连接的协议
可靠地数据传送。
2:UDP(User Datagram Protocol,数据用户报协议)
无连接协议:不需要双方进行连接,仅对指定的套接字地址发送数据。所以其向套接字传送数据都需要附上接收方套接字地址(IP+port)
不可靠数据传输:相比TCP的各种拥塞阻塞机制、差错纠错机制等,UDP仅提供传输服务,不保障数据完整正确到达。
针对吞吐量和定时:运输层在现代一般都能给出满意的速度,但并不能提供任何保证。
应用层协议
定义:一个应用层协议,应当具备如下:
数据类型:交换的报文类型,如请求报文和响应报文的类型。
报文语法:报文中,各个字段如何安排内容。语法如中文:主谓宾--这是我的苹果。报文也是类似,如:host:www.baidu.com 。通常为:单词或短语 + " : " + 字段语义。
字段语义:每个字段中的信息的含义。
如何传输:确定一个进程何时、如何发送报文,及对报文响应的规则。
RFC:Request For Comments,请求评论。这个文档集合,定义了诸多的互联网协议相关信息。
HTTP协议(RFC1945、RFC2616定义)--- Web
说明:是一个拉协议,将数据拉过来。
协议规范:
数据类型:html、图片、附件、超链接等
报文语法:名词组 :字段内容
传输方式:TCP
说明:超文本传输协议,无状态协议,主要用于web应用层协议。使用TCP作为运输层协议。
web客户端进程(如浏览器)实现了http的客户端,web服务器实现了http的服务端。
持续连接和非持续连接
HTTP两者都可以采用,持续连接相对于非持续连接,RTT(Round-Trip Time,往返时间)更短,服务器负担更轻。
报文格式:
-
请求报文:
请求行:[请求方式] [请求URL] [所用HTTP版本] 如:GET /news/48781.html HTTP/1.1
-
请求头部:(也称首部行) 有多个字段行组成。其包含众多内容协商首部行,其主要针对接收服务器进行告知。
如:Connection:close,告知服务器这是非持续连接。User-agent:Mozilla/5.0 ,告诉服务器当前客户端使用的是火狐5.0版本,服务器通常针对不同浏览器可以提供不同的数据版本。
请求数据:(实体部分,entity body)当用POST请求时,在这里传入数据。
-
响应报文:
响应行:(状态行) [HTTP版本] [状态码] [状态信息]
响应头:多个字段行。包含服务器版本、当前日期、改文件上次修改日期等待。
响应数据:
用户与服务器交互:Cookie:
作用:HTTP是无状态协议,不保存之前会话的内容。如果客户本次请求,需要之前的会话数据作为支撑,则可以使用Cookie来进行保存。
实现:当服务器第一次给予某特定客户端(某主机上的浏览器)一个Cookie后:Set-cookie:1234,该Cookie会保存在客户浏览器中,并在下次访问该服务器时,将Cookie作为首部行的一个字段内容传入。
组件:①位于请求报文中的Cookie首部行 ②位于响应报文中的Cookie首部行 ③位于客户代理浏览器的缓存文件。 ④位于服务器的后端数据库。
web缓存(也称代理服务器proxy server)
作用:减少接入ISP的流量强度,及向上层ISP所付的流量费,同时也可以减少用户时延提高服务。具体实现为内容分发网CDN。
实现:在ISP处,安装一个web缓存服务器集群,拦截用户对网页的访问。当有客户请求时,其作为服务器,查询自身是否储存了客户的请求对象(html文件、流视频、图片等),如果没有就会访问实际请求服务器,获得对象发给用户,并储存在自己的主机上。
条件GET方法:
作用:使用web缓存时,就算当前服务器有客户需求的对象,但可能改对象已经修改,此时需要web缓存服务器作为客户端,向实际服务器发送一个条件GET的请求报文,如果实际服务器的上次修改时间早于web缓存接收文件的时间,则不返回数据,否则返回最新的对象。
SMTP协议(Simple Mail Transfer Protocol,简单邮件传输协议、RFC 5321)
说明:是一个推协议,将数据推出去。邮件服务器端口110.
协议规范:
数据类型:附件、超链接、html、图片。(运输时会转码成7位ASCII码)
语法格式:名词组 :字段内容
传输方式:TCP
电子邮件组成部分:①2个用户代理(如163邮件应用)②2个客户邮件服务器(含有两个客户的邮箱) ③SMTP
*每个客户有一个邮件服务器,邮件服务器通过STMP互相传递邮件。
握手步骤:①HELO ②MAIL FROM: ③RCPT TO: ④ DATA:(包含数据)⑤ . (代表发送完毕) ⑥QUIT断开STMP连接
- DATA:在最前面必须包含的是:From: 、 To: 、 Subject: 和其他可选首部行
消息传递:发送者 --》发送者邮件服务器 --》接收方邮件服务器 --》接收方
使用协议:发送者 --STMP/HTTP-- 发送者邮件服务器 -- STMP(唯一) -- 接收方邮件服务器 -- POP3、IMAP、HTTP -- 接受者
诠释:因为STMP是推协议,在接收方想要获得邮件时,必须要用其他协议:POP3(Post Office Protocol-Version 3,邮局协议3)、IMAP(Internet Mail Access Protocol,因特网邮件访问协议)、HTTP。
POP3(RFC 1939定义)
说明:很简单的邮件访问协议。
获取邮件步骤:
①特许:用户代理(邮件应用)发送用户名和口令鉴别用户。
②事务处理:用户代理取回报文,并可以对报文标记删除记号、取消标记、获得邮件的统计信息等。
③当客户发出quit命令后,结束该POP3会话,这是服务器进行更新:删除那些被标记了删除记号的报文。
Linux访问:可以用telnet进行远程访问,如:
telnet qq.mail.com 110 /*一问一答模式*/
+OK POP3 server ready
user sunlin
+OK
pass key
+OK user successfully logged on
IMAP(RFC 3501)
说明:比POP3功能更丰富,但是更复杂。
DNS(Domain Name System,RFC 1034、1035)
说明:域名系统,用于定位计算机位置的协议。端口:53.
主要任务:
①由分层的DNS服务器实现的分布式数据库。(主要三层结构)
②是一个主机能够查询该数据库的应用层协议。
DNS服务器通常运行在BIND软件的UNIX机器上。
功能:
查询IP地址
根据主机别名(host aliasing)得到规范主机名(canonical hostname)。
根据邮件服务器别名,得到规范主机名。(一个公司的邮件服务器别名可以和web服务器别名一样)
负载分配:一个主机集合(IP地址集合,具有多台不同主机,运行同一个Web服务器)与一个规范主机名想联系。客户请求一个DNS请求时,该服务器用IP地址的整个集合进行相应。(每次回答会让集合内顺序改变,以达到平均负载效果)
设计机理:DNS是分布式设计,因为其涵盖了全世界的电脑、手机等端系统。这种超广范围,产生如下问题:
单点故障:如果只有一处有服务器,当它崩溃,则整个Internet瘫痪。
通信容量:单个服务器不得不处理所有DNS查询IP,用于为上亿台主机产生所有的HTTP、STMP请求。
远距离的集中式数据库:如果数据库集中在某个国家,则对距离远的地方,时延极大。
维护:单个服务器的庞大数据量使维护更难。
分布式、层次数据库:
①根DNS服务器
②顶级域DNS服务器(Top-Level Domain,TLD):包含com服务器、org服务器、edu服务器等等
③权威DNS服务器:如facebook DNS服务器等专门为某些具体公司提供域名查询的服务器。
本地DNS服务器:虽然没有在层次结构中,但确是不可忽略的一环。一般位于接入ISP的机房。是家庭、公司所访问的第一个DNS服务器。
查询IP地址流程:(设查www.baidu.com)
①发送给本地DNS服务器一个DNS报文。
②本地DNS服务器会访问根DNS服务器,根DNS服务器随即查询对应顶级域的服务器地址并返回给本地DNS服务器。如com顶级域(通常都已经缓存了顶级域服务器地址,所以会省略这个)
③本地DNS根据(返回的)地址,访问顶级域DNS服务器,并得到权威DNS服务器,如baidu.com的权威dns服务器地址。
④本地DNS根据该地址,访问权威DNS服务器,并得到www.baidu.com的实际IP地址。
⑤本地DNS服务器将该地址返回给用户,用户将直接和该IP地址进行运输层连接。
注意:通常第三步,有可能TLD服务器会传回一个中间服务器,在通过中间服务器得到权威服务器的地址。
递归和迭代:上述中,用户和本地DNS服务器是递归方式查询,而本地DNS和分布式DNS服务器是迭代查询。其方式也可以更改成全部迭代查询,或者全部递归查询。但由于本地DNS服务器要进行缓存,所以一般采取上述形式。
DNS记录和报文:
DNS分布式数据库的所有服务器储存了资源记录(Resource Record,RR),RR提供了主机名到IP地址的映射。
记录:DNS服务器中的每个资源,以四元组(Name,Value,Type,TTL)出现。(TTL是该记录生存时间)
-
Type:其值决定Name和Value的形式。(以下先暂时省略TTL)
Type=A:address,则Name为主机名,Value为对应的IP地址。如:(relay1.bar.foo.com,145.37.93.126,A)
Type=NS:Name Server,则Name是一个域(如 foo.com),而Value对应的分布式结构中更下一层的服务器名。此记录用于查询链中。如:(foo.com,dns.foo.com,NS)
Type=CNAME:Canonical Name,则Name是一个别名服务器名,Value是其对应的规范主机名。如:(foo.com,relay1.bar.foo.com,CNAME)
Type=MX:Mail,Name是一个邮件服务器别名,Value是其对应的规范主机名。如:(foo.com,mail.bar.foo.com,MX)。
DNS报文及插入数据:详情查看P90,也不是很详细,没有例子。
P2P文件分发 和 视频流、内容分发网
详情查看p97以后。
第三章:运输层
可靠数据传输(Reliable Data Transmission,RDT)
依赖多种机制来实现的,一般假设下层为不可靠数据传输urt的:
校验和:将分组中,每16个bits作为元素相加,进位则回卷(0位+1),结果进行取反。
定时器:用于确认分组是否丢失,会产生超时事件,则会进行重传。还可以用于定时分组在网络中存活时间,以确保不会在网络中出现同一个序号的分组(不同数据包中)。
序号:用于确认分组,以确保按序接收。
ACK-确认:当正确收到时,发送这个。
NAK-否定:当没正确收到,发送这个。
窗口、流水线:通过设置窗口长度(一次允许发送的分组数),一次允许发送多个分组,在窗口中的分组可能的状态是:已发送已确认、已发送未确认、未发送将发送。窗口前后的分组状态分别为:已发送已确认,咱不能发送。
TCP:面向连接的运输协议(connection-oriented)
说明:TCP是逻辑连接,其共同状态仅保留在端系统的TCP程序中。不像电路交换的频分复用(FDM)和时分复用(TDM),是建立了物理连接。
全双工服务(full-duplex service):不同主机上的进程A、B建立了TCP连接,则应用层数据可以同时双向传递。
点到点:单个发送方于单个接收方之间的连接。(与之相对的是多播,TCP无法实现)
过程:
1.三次握手:
①当客户进程想要与服务器进程建立连接时,客户进程A会发送一个特殊TCP报文段(SYN 报文段,syn=1)。
②服务器进程B收到并发送一个特殊的TCP报文段(SYNACK报文段,syn=1)来响应。
③最后客户收到,并发送第三个特殊报文段(该段及后续报文段:syn=0)作为响应。(前两个TCP报文段不包含应用层数据)如此,便建立了TCP连接。
2.数据传送:
①应用进程通过TCP套接字,发送数据流。TCP引导数据到发送缓存(send buffer,由三次握手时设置)。
②接下来TCP会不时从发送缓存里取出数据,配上TCP首部(通常20字节),形成多个TCP报文段(TCP segment),以报文段形式发送到网络层。
③网络层将报文段封装首部(通常20字节),形成IP数据报,并传入网络中。
④接收方根据②③逆序方式,得到TCP报文段中的数据,并将其放入TCP连接的接收缓存中,应用程序从接受缓存读取数据流。并发送ACK响应报文到发送方。
MSS:Maximum Segment Size,最大报文段长度。指应用层数据的最大长度,根据本地最大链路层帧长度(最大传输单元,Maximuum Transmission Unit,MTU)来设置。MTU通常为1500字节,所以MSS通常为1460字节,40字节是TCP\IP首部长度。
TCP连接组成:每台主机上都有的缓存(接收、发送)、变量、(与进程连接的)TCP套接字。中间链路中包含路由器、链路交换机都不给TCP连接分配任何缓存和变量。
TCP报文段结构
//如当用 wireshark 嗅探HTTP报文时,可以在报文里TCP中按序找到下列的各个字段。
首部:(依次书写)
源端口号(2字节)| 目的端口号(2字节):用于应用进程的多路复用、分解。
-
()序号字段*(32bits):实现可靠传输的关键部分。其内容是TCP报文段中的首个字节的序号。TCP是按照数据的字节流进行排序,而不是对每个报文段排序。
如一个应用层数据文件分成100个报文段,每个报文段MSS=1000字节,则第二个报文段的序号会填写:1000。此处假设序号从0开始,但实际中常常是随机的,以避免出现网络存在的,旧的同端口报文被误认的情况;
注意:序号和确认号都是实际数据的字节序号,其不包含TCP\IP的头部。如一个只有头部的TCP报文段,是不增加接收方的确认号的。
-
()确认号字段*(32bits):实现可靠传输的关键部分,用于全双工实现。当主机A向B发送TCP报文段时,B也会向A发送报文段。
其字段内容为:主机A期望从主机B中收到的下一字节的序号。
如当前主机A收到了0~535序号的字节流,则会填写536到该字段。注意,确认号字段是从连接开始,一直到连接结束,从B到A发送的所有字节流,不一定是连续的一个报文段。(可以用 telnet协议应用来进行序号、确认号测试)
首部长度字段(4bit):由于选项字段通常为空,所以常为20字节。 | 保留未用 | 包含ACK等确认号 |
-
保留未用、标志字段(flag field):CWR、ECE、URG、ACK、PSH、RST、SYN、FIN等信息,共12bits。
SYN:可能是同步的意思(sync)。用于三次握手中的前两次。
FIN:用于断开连接时进行设置:fin=;如:一端A发送报文段,设置FIN=1,接收方B接收后,回复ACK确认(不包含FIN=1)。一段时间后,接收方B发送FIN=1报文段,随后关闭。发送方A接收到后,会再发送ACK,定时如30秒后随即关闭。
RST:当某主机接收到一个请求连接,但是该端口没有使用,则返回给发送IP地址方,一个包含RST=1的segment,告知其这个端口不可用不要再发数据。(如nmap等工具常常用RST来测探一个主机的防火墙[收到RST]、TCP连接的端口号是否打开[是否接收到返回报文段及内容])
ECE:(Explicit Congestion notification Echo,明确阻塞通知回送),用于接收方向发送方传递ECN明确阻塞通知,ECN是一种网络辅助拥塞控制,当链路中路由器阻塞(由路由器生产商确认)时,会将IP数据报中的ECN置1,随后接收方接收到该信息,并回送ACK时,将ECE位置1,明确地告知发送方,TCP连接阻塞。
CWR:(Congestion Window Reduced,拥塞窗口减少),当发送方接收到ECE置1的ACK时,下次传送报文段时,会将CWR置1,告知拥塞窗口以减少。
接收窗口(16bits):用于流量控制。显示接收方愿意接收的字节数量,即接收方的 ReceivedBuffer - (LastByteRead - LastByteReceived)的值(接收缓存的空间大小)。当接收窗口=0时,发送方会定时发送一个数据只包含一个字节的报文段到接收方,以免长时间阻塞。
因特网校验和(16bits):用于校验TCP中的数据。TCP以16比特为一个计算单位。
紧急数据指针(16bits)(urgent data pointer field):当紧急数据存在并给出指向紧急数据尾指针的时候,TCP必须通知接收端的上层实体。(通常实际中没有使用包含PSH、URG、紧急数据指针,提到只是为字段了完整性。)
选项(32bits):(可选和可变长)该字段用于发送方和接收方协商最大报文段长度(MSS),或者高速网络环境下用于窗口调节因子时使用。
异常处理
说明:当发生{差错恢复(丢包、比特错误、比特丢失)、接受缓存不够、网络堵塞}等情况时,TCP采用{重传、流量控制、拥塞控制}的处理方法。
-
超时间隔(TimeoutInterval)
说明:超时间隔是主要的判读数据丢失的方法。
采用公式:
timeoutInterval = estimatedRTT + 4 * DevRTT (estimated是估计的平均往返时间、DevRTT是实际与平均的差值)
estimatedRTT = (1-α)esitmatedRTT + α * SampleRTT (SampleRTT是报文段发送并收到确认的时间)
更新:TCP中,是以报文段中最小序号的那位计时。当第一次接收到数据,或者接收到确认时(前面所有序号的报文段已正确确认),会进行更新。
-
快速重传
说明:当主机收到3个冗余ACK时,也会触发重传机制。
冗余ACK:由于主机A已收到主机B的确认码ACK(也可以说请求码),如510,才会发送序号为510的报文段。但主机又再次收到主机B的报文段,说明报文段(序号=510)可能丢失了。
但也可能是错序收到,主机B先收到1510的报文,此时欠缺510~1509,所以会发送510ACK的报文段,但隔一会收到510的段,此时他会正常返回一个报文段(ACK=1510)。
如果连续三次收到ACK,说明丢失的可能性很大,则选择重传以避免太大时延。
-
流量控制(针对接收方的接收缓存大小)
说明:TCP协议必须保证接收方的接受缓存不会溢出。所以用TCP首部【接收窗口】字段来表示给对方,自己的接受缓存大小。接受窗口可看上述TCP报文段格式。
-
拥塞控制(针对网络的阻塞程度)
说明:可以用加倍超时间隔(凡是超时,就加倍,但当正常地收到ACK时,会重新进行公式计算,恢复正常),下面专题研究。
拥塞控制:Congestion Control(端到端拥塞控制)
三大机制:慢启动、拥塞避免、快速恢复。
说明:拥塞机制,和快速重传、流量控制相互交织,但自有主体。拥塞控制主要是针对超时、三次冗余事件,而流量控制则是针对目的主机的接受窗口大小和当前已发送未确认的报文段大小来控制。
所用变量说明:
cwnd变量(congestion window):用这个值来进行发送方输出流量速率控制。
ssthresh变量(slow start thresh,慢启动阈值):用来作为改变状态的标准。
注意:以下三大机制的介绍,是在将rwnd(接受窗口)想象成无限大时进行,因为min{ rwnd、cwnd }是衡量输出速率的标准,将rwnd无限大,可以将注意力放到cwnd上。
慢启动(slow-start):
-
状态描述:
设置cwnd=1;
随后每当接收一个ACK时:cwnd += 1 MSS。因为cwnd一次有多个,所以当全部确认时,其cwnd(确认之后初始值)= cwnd(确认之前)+ cwnd (个MSS)。
所以其呈现的是每次cwndRTT(cwnd中第一个报文发出,到收到最后一个报文的ACK),cwnd=2;呈现指数增长*,但是实际上,其是每个RTT(一个报文段发送,并收到该报文段的ACK)增加 1 。
-
改变状态:
三个原因:
①首次出现超时事件:
触发操作:
ssthresh = cwnd / 2;
cwnd = 1;
随后如初始时一样,每RRT增长一倍。
②cwnd >= ssthresh:(ssthresh是由上次的超时事件确定)
触发事件:
进入拥塞避免状态
②出现3个冗余ACK(总共接收到4个同序号ACK):进入快速恢复状态。(非强制,也可以直接进入拥塞避免状态,如老版的TCP Tahoe)
拥塞避免:
-
状态描述:当由慢启动、快速恢复状态进入拥塞避免状态后,每次RRT不再增加一倍,而是谨慎地增加1。
cwnd >= ssthread; //进入该状态时的初始状态
cwnd += MSS*(MSS/cwnd); //每次收到一个ACK,便增加 MSS *(MSS/cwnd),所以cwnd中报文段全部确 //认时,增加1
-
状态改变:
两个原因:
①出现超时事件:
触发操作和事件:
ssthresh = cwnd /2 ;
cwnd = 1;
进入慢启动状态。
②出现三次冗余ACK:和慢启动中出现三次冗余一样。
快速恢复:(非强制状态。三次冗余ACK比之超时,对待更柔和)
-
状态描述:当由其他状态进入快速恢复状态后:
初始状态:
dupACKcount ==3;
ssthresh = cwnd /2;
cwnd = ssthresh + 3*ACK;
//以后对收到的每个冗余ACK,cwnd += 1,直到状态改变。
-
状态改变:
两种原因:
①出现超时事件:
则和上述状态都一样。
②接收到一个特定的ACK确认报文段(导致进入快速恢复的那个似丢失报文段的ACK信息)
则触发操作和时间:
cwnd = ssthresh; //降低了cwnd数量
进入拥塞避免状态,重置冗余ACK计数。
拥塞控制总说:可以用AIMD来表示(Additive-Increase Multiplicative-Decrease,加性增-乘性减(减半))。所以图示可能会成为锯齿状。(忽略最开始或超时后短时间的慢启动阶段)
高度简化的宏观模型:设出现超时时,W=cwnd,且W几乎不变。则:
平均吞吐量= (0.75*W) / RTT (此处RTT是一个cwndRTT窗口长度w的往返时间,也设几乎不变,模型中忽视了 慢启动状态,因为指数增长很快,所以假设每次超时后,cwnd = W /2;)
演化:TCP的拥塞控制以及演化了多年,并且仍在演化中,以适应未来更高速的TCP连接(如网格、云计算等)。以后或许可以研究这个。
公平性:当k条TCP连接,通过同一个带宽为R瓶颈链路时,不考虑其他影响因素情况下,TCP拥塞控制是否是公平的呢?即不同时间点,每条TCP连接中的输出速率不同。当每条TCP获得R/k的带宽时称为公平的。
通常来说,理想下的情况,TCP是可以实现公平性的。但是在实际情况中,RTT越小的TCP连接,能更快地抢占带宽,导致不公平。如书中P184所讲述的例子。还有如web浏览器发送并行TCP连接时,会占用更多的带宽,这也是不公平的。