第1章 计算机网络和因特网
1.1什么是因特网
协议:定义了在两个或多个通信实体之间交换的报文的格式和顺序,以及报文发送/或接受一条报文或其他事件所采取的动作。
1.2.网络边缘
光纤分布体系结构:主动光纤网络(AON);被动光纤网络(PON)
1.3.网络核心
分组交换的性能够优于电路交换的性能。
网络的网络:

1.4传输时延和传播时延、丢包和吞吐量
传输时延是路由器推出分组所需要的时间,它是分组长度和链路传输速率的函数,而与两台路由器之间的距离无关。
传播时延是一个比特从一台路由器传播到另一台路由器所需要的时间,它是两台路由器之间距离的函数,而与分组长度或链路传输速率无关。
吞吐量取决于数据流过的链路的传输速率,而且取决于干扰流量。
因特网的协议栈五个层次:物理层、链路层、网络层、运输层和应用层。
报文(message):应用层的协议分布在多个端系统上,一个端系统1中应用程序使用协议与另一个端系统中的应用程序交换信息分组。这种位于应用层的信息分组称为报文。
运输层:在应用程序端点之间传送应用层报文。有两种运输协议,即TCP和UDP。
报文段(segment):运输层的分组。
TCP:将长报文划分为短报文,并提供拥塞控制机制,因此当网络拥塞时,源抑制其传输速率。
UDP:向它的应用程序提供无连接服务,不提供不必要服务,不保证可靠性,没有流量控制,也没有拥塞控制。
瞬时吞吐量:主机B接受到该文件的速率(bps)
1.6.面对攻击的网络
Dos:拒绝服务攻击
Dos攻击三种类型:
1. 弱点攻击
2. 带宽洪泛
3. 连接洪泛
分布式Dos,攻击者控制多个源并让每个源向目标猛烈发送流量。
总结
用来观察执行协议实体之间交换的报文的基本工具称为分组嗅探器。它可以显示出这些被捕报文的各个协议字段的内容。
计算机网络分层的必要性

第2章
2.1应用层协议原理
1 网络应用程序体系结构
传输层向应用层提供服务
应用程序体系结构:由应用程序研发者设计,规定了如何在各种端系统上组织该应用程序。
客户-服务器体系结构
服务器服务于来自许多其他称为客户的主机的请求。例如Web应用程序,当Web服务器接收到来自某客户对某对象的请求时,它向该客户发送所请求的对象作为响应。(80端口)
缺陷:可拓展性较差,可靠性差
P2P体系结构
对位于数据中心的专用服务器有最小的依赖,相反,应用程序在间断连接的主机对之间使用直接通信,这些主机称为对等方。如,文件共享(BitTorrent), 因特网电话和视频会议。

2 进程通信
进程(process)
一个进程可以被认为是运行在端系统中的一个程序。
TCP上的socket(套接字):代表本地和对方的ip和端口的标识,只作用于本地;只有应用层和传输层知道,一种约定。是四元组的一个具有本地意义的标识。
四元组:源ip,源port,目标ip,目标port ;
UDP上的socket:二元组的一个具有本地意义的标识, 二元组:本地ip和本地端口。
客户和服务器进程
在一对进程之间的通信会话场景中,发起通信(即在该会话开始时发起与其它进程的联系)的进程被标识为客户,在会话开始时等待联系的进程是服务器。
进程与计算机网络之间的接口
进程通过一个称为套接字的软件接口向网络发送报文和从网络接受报文。
套接字是同一台主机内应用层与运输层之间的接口。称为应用程序和网络之间的应用程序编程接口(API)
进程寻址
在一台主机上运行的进程为了向在另一台主机上运行的进程发送分组,接受进程需要有一个地址。为了标识接受进程,需要定义两种信息:1.主机的地址;2.在目的主机中指定接受进程的标识符。

3 因特网提供的运输服务
TCP服务
面向连接服务和可靠数据传输服务
具有拥塞控制机制
UDP服务
不提供不必要的轻量级运输协议,仅提供最小服务,是无连接的,在两个进程通信前没有握手过程;提供一种不可靠数据传送服务。
因特网运输协议所不提供的服务
没有提供吞吐量和定时服务
4 应用层协议
把报文发送进套接字实现网络进程间的相互通信。
应用层协议定义了运行在不同端系统上的应用程序进程如何相互传递报文
定义了:交换的报文类型
各种报文类型的语法
字段的语义
确定一个进程何时以及如何发送报文,对报文进行响应的规则。
5 HTTP概况
HTTP:超文本传输协议,是Web的核心
HTTP由两个程序实现:一个客户程序和一个服务器程序。客户程序和服务器程序运行在不同的端系统中,通过交换HTTP报文进行会话。
HTTP使用TCP作为它的支撑运输协议,客户端的套接字接口是客户进程与TCP连接之间的门,在服务器端的套接字接口则是服务器进程与TCP连接之间的门。
HTTP是一个无状态协议,不保存关于客户的任何信息。
2.2 Web和HTTP(超文本传输协议)
2.2.2 非持续连接和持续连接
1. 采用非持续连接的HTTP
每个TCP连接在服务器发送一个对象后关闭,即该连接并不为其他的对象而持续下来。
每个TCP连接只传输一个请求报文和一个响应报文。
往返时间(RTT)
该时间是指一个短分组从客户到服务器然后再返回客户所花费的时间。
包括分组传播时延、分组在中间路由器和交换机上的排队时延以及分组处理时延。

三次握手
客户向服务器发送一个小的TCP报文段,服务器用一个小TCP报文段做出确认和响应;(一次握手)
客户向服务器返回确认;(二次握手)
完成三次握手的前两个部分后,客户结合三次握手的第三部分(确认)向该TCP连接发送一个HTTP请求报文。
该请求报文到达服务器后,服务器就在该TCP连接上发送(Web应用如HTML)文件
总的响应时间就是两个RTT加上服务器传输HTML文件的时间。
缺点
Web服务器负担大,客户和服务器都要分配TCP的缓冲区和保持TCP变量。
时间长;每个对象经受两倍RTT的交付时延,即一个RTT用于创建TCP,另一个RTT用于请求和接受一个对象。
2.采用持续连接的HTTP
在采用HTTP1.1持续连接的情况下,服务器在发送响应后保持该TCP连接打开,在相同的客户与服务器之间,后续的请求和响应报文能够通过相同的连接进行传送。一个完整的Web页面可以用单个持续TCP连接进行传送。
2.2.3HTTP报文格式
HTTP响应报文

HTTP请求报文第一行叫请求行,后继的行叫首部行,请求行三个字段:方法字段、URL字段和HTTP版本字段。绝大部分HTTP请求报文使用GET方法。
HTTP响应报文

三个部分:初始状态行,6个首部行,实体体(entity body)
状态行3个字段:协议版本字段、状态码、相应状态信息
状态码及其相应短语指示了请求的结果
常见的:
2.3 因特网中的电子邮件
电子邮件系统的三个主要组成部分:用户代理,邮件服务器,简单邮件传输协议(SMTP)

SMTP限制所有邮件报文的体部分只能采用简单的7比特ASCII表示

2.4 DNS:因特网的目录服务
我们需要一种能进行主机名到IP地址转换的目录服务,这就是域名系统的主要任务。
DNS(Domain Name System,域名系统)是:一个有分层的DNS服务器实现的分布式数据库;一个使得主机能够查询分布式数据库的应用层协议。DNS服务器通常是运行BIND软件的UNIX机器。DNS协议运行在UDP之上,使用53号端口。
DNS通过采用了位于网络边缘的客户和服务器,实现了关键的名字到地址转换功能。
DNS还提供了一些重要的服务:主机别名;邮件服务器别名;负载分配。
DNS是一个分布式数据库:
分布式、层次数据库
根DNS服务器、顶级域DNS服务器和权威DNS服务器。

从理论上讲,任何DNS查询既可以是迭代的也能是递归的。实践中,查询通常遵循:从请求主机到本地DNS服务器的查询是递归的,其余的查询时迭代的。
DNS缓存
DNS缓存为了改善时延性能并减少在因特网上到处传输的DNS报文数量。在一个请求链中,当某DNS服务器接受一个DNS回答时,它能将映射缓存在本地存储器中,如果在DNS服务器中缓存了一台主机名/IP地址对,另一个对相同主机名的查询到达该DNS服务器时,该服务器就能够提供所要求的IP地址。
2.5 P2P(略)
2.6 视频流和内容分发网
在HTTP流中,视频只是存储在HTTP服务器中作为一个普通的文件,每个文件有一个特定的URL。
为适应不同客户的带框大小,研发了经HTTP的动态适应性流(DASH)。
CDN-内容分发网
CDN的两种不同的服务器安置原则:
1.深入
2.邀请做客
CDN操作
当用户主机中的一个浏览器指令检索一个特定的视频(由URL标识)时,CDN必须截获该请求,以便能够:1.确定此时适合用于该客户的CDN服务器集群;2.将客户的请求重定向到该集群的某台服务器。
大多数CDN利用DNS来截获和重定向请求;
2.7 TCP UDP套接字编程-生成网络应用(重要)
典型的网络应用是由一对程序(即客户程序和服务器程序)组成的,它们位于两个不同的端系统中,当运行这两个程序时,创建了一个客户进程和一个服务器进程,同时它们通过从套接字读出和写入数据在彼此之间进行通信。
网络应用程序有两类:
1. 由协议标准(如RFC)中所定义的操作的实现。独立的程序员开发的客户和服务器程序间可以通信。
2.专用的网络应用程序。开发者用他的代码完全控制该代码的功能。但是因为这些代码并没有实现一个开放的协议,其他独立的开发者将不能开发出和该应用程序交互的代码。

2. UDP套接字编程
当使用UDP时,必须先将目的地址附在分组之上,在该分组传过发送方的套接字之后,因特网将使用该目的地址通过因特网为该分组选路到接收进程的套接字。当分组到达接收套接字时,接收进程将通过该套接字取回分组,然后检查分组的内容并采取适当的动作。每一个进程具有一个或多个套接字,所以在目的主机指定特定的套接字也是必要的。当生成一个套接字时,就为它分配一个称为端口号的标识符。该目的地址是由目的主机IP地址和目的地套接字的端口号组成。发送方的源地址也是由源主机的IP地址和源套接字的端口号组成,该源地址也要附在分组之上。

1.UDPClient.py
from socket import * #形成在Python中所有网络通信的基础,我们能够在程序中创建套接字
severName = 'hostname' #提供或者包含服务器的IP地址或者包含服务器的主机名的字符串,使用主机名,则自动执行DNS lookup从而得到IP地址
severPort = 12000 #端口号设置
clientSocket = socket(AF_INET, SOCK_DGRAM) #创建了客户的套接字,称为clientSocket, AF_INET:示了底层网路使用了IPv4;第二个参数指示了套接字类型为UDP套接字而不是TCP套接字。
message = raw_input('Input lowercase sentence:')#用户输入信息
clinetSocket.sendto(message.encode(), (severName, serverPort))#首先将报文由字符串类型转换为字节类型,因为我们需要向套接字中发送字节;方法sendto()为报文附上目的地址并且向进程的套接字clinetSocket发送结果分组
modifiedMessage, serverAddress = clientSocket.recvfrom(2048) #当一个来自因特网的分组到达该客户套接字时,该分组的数据被放置到变量modifiedMessage中,其源地址被放置到变量severAddress。
print(modifiedMessage.decode()) #将报文从字节转化为字符串后,在显示器上打印出modifiedMessage
clientSocket.close() #该行关闭了套接字,然后关闭了该进程
2. UDPServer.py
from socket import *
serverPort = 12000
serverSocket = socket(AF_INET, SOCK_DGRM)
serverSocket.bind(('',serverPort))
print("The server is ready to receive")
while True:
message, clientAddress = serverSocket.recvfrom(2048)
modifiedMessage = message.decode().upper()
serverSocket.sendto(modifiedMessage.encode(), clientAddress)
serverSocket.bind(('',serverPort)) --- 这行将端口号12000与该服务器的套接字绑定(即分配)在一起。因此在UDPServer中,代码显示地为该套接字分配一个端口号,以这种方式,当任何人向位于该服务器的IP地址的端口12000发送一个分组,该分组将导向该套接字。UDPServer然后进入一个while循环;该while循环将允许UDPServer无限期地接收并处理来自客户的分组。
3.TCP套接字编程
TCP是一个面向连接的协议,这意味着在客户和服务器能够开始相互发送数据之前,它们先要握手创建一个TCP连接。TCP连接的一端与客户套接字相联系,另一端与服务器套接字相联系。

客户程序创建一个TCP套接字,生成其TCP套接字时,指定了服务器中的欢迎套接字的地址,即服务器主机的IP地址及其套接字的端口号。生成其套接字后,该客户发起了一个三次握手并创建与服务器的一个TCP连接。

第3章 运输层
3.1 概述和运输层服务
运输层协议为运行在不同主机上的应用进程之间提供了逻辑通信功能。在发送端,运输层将从发送应用程序进程接收到的报文转换成运输层分组,用因特网术语来讲该分组称为运输层报文段(segment)
运输层和网络层的关系
网络层提供了主机之间的逻辑通信,而运输层为运行在不同主机上的进程之间提供了逻辑通信。
如果网络层协议无法为主机之间发送的运输层报文段提供时延或带宽保证的话,运输层协议也就无法为进程之间发送的应用程序报文提供时延或带框保证。
3.2 多路复用与多路分解
一台主机同时运行多个进程,一个进程有一个或多个套接字,它相当于从网络向进程传递数据和从进程向网络传递数据的门户。
我们现在考虑接收主机怎样将一个到达的运输层报文段定向到适当的套接字:
在接收端,运输层检查这些字段,标识出接收套接字,进而将报文段定向到该套接字。将运输层报文段中的数据交付到正确的套接字的工作称为多路分解。
在源主机从不同套接字中收集数据块,并为每个数据块封装上首部信息(这将在以后用于分解)从而生成报文段,然后将报文段传递到网络层,所有这些工作称为多路复用。
运输层多路复用要求:
1. 套接字有唯一标识符;
2. 每个报文段有特殊字段来指示该报文所要交付的套接字。

端口号是一个16比特的数,有一些端口号是周知端口号,如HTTP的80号端口,FTP使用端口号21.
1.无连接的多路复用与多路分解
一个UDP套接字是由一个二元组全面标识的,该二元组包含一个目的IP地址和一个目的端口号。

面向连接的多路复用与多路分解
TCP套接字是由一个四元组(源IP地址,源端口号,目的IP地址,目的端口号)来标识。当一个TCP报文段从网络到达一台主机时,该主机使用全部4个值来将报文段定向(分解)到相应的套接字,不同与UDP的是,两个具有不同源IP地址或源端口号的到达TCP报文段将被定向到两个不同套接字,除非TCP报文段携带了初始创建连接的请求。

3.3 无连接运输:UDP
有许多应用更适合用UDP,原因主要有以下几点:
关于发送什么数据以及何时发送的应用层控制更为精细。实时应用通常要求最小的发送速率,不希望过分地延迟报文段的发送,且能容忍一些数据丢失, TCP服务模型有一个拥塞控制机制,并不是特别适合这些应用的需要。
无须连接建立。TCP在开始数据传输之前要经过三次握手。UDP却不需要任何准备即可进行数据传输。因此UDP不会引入建立连接的时延。这可能是DNS运行在UDP之上而不是运行在TCP之上的主要原因。
无连接状态。 UDP不维护连接状态,也不跟踪这些参数。某些专门用于某种特定应用的服务器当应用程序运行在UDP之上而不是TCP之上,一般能支持更多的活跃客户。
分组首部开销小。每个TCP报文都有20字节的首部开销,而UDP仅有8字节的开销。
3.3.1 UDP报文段结构


UDP首部只有4个字段,每个字段由两个字节组成。
长度字段指示了在UDP报文段中字节数(首部加数据)。接收使用校验和来检查在该报文段中是否出现了差错。
3.3.2 UDP校验和
UDP检验和提供了差错检测功能。
3.5 面向连接的运输:TCP
3.5.1 TCP连接
TCP被称为是面向连接的。
TCP协议只在端系统中运行,不在中间的网络元素中运行,中间的网络元素中不会维持TCP连接状态。
TCP连接总是点对点。
三次握手:建立TCP连接的过程中,客户首先发送一个特殊的TCP报文段,服务器用另一个特殊的TCP报文段来响应,最后,客户再用第三个特殊报文段作为响应。前两个报文段不承载“有效载荷”,也就是不包含应用层数据;而第三个报文段可以承接有效载荷。
MSS:最大报文段长度,限制报文段数据字段的最大长度
MTU:最大传输单元

3.5.2 TCP报文段结构
TCP报文段由首部字段和一个数据字段组成。数据字段包含一块应用数据。


主机A填充进报文段的确认号是主机A期望从主机B收到的下一个字节的序号。
累计确认
当主机在一条TCP连接中收到失序报文段时该怎么办?
两个基本选择:1.接收方立即丢失失序报文段。2.接收方保留失序的字节,并等待缺少的字节以填补该间隔。这种做法对网络带宽而言更为有效。
一个报文段的序号就是该报文段数据字段首字节的序号。
确认号就是主机正在等待的数据的下一个字节序号。

第一个报文段:客户发往服务器序号字段是42
第二个报文段:由服务器发往客户。两个目的:首先它是为该服务器所收到数据提供一个确认。通过在确认号字段中填入43,服务器告诉客户它已经成功地收到字节42及以前的所有字段,现在正等待字节43的出现。
第三个报文段:从客户发往服务器的。它的唯一目的是确认已从服务器收到的数据。
3.5.5 流量控制
TCP 为它的应用程序提供了流量控制服务(flow- control service) 以消除发送方使接收方缓存溢出的可能性。流量控制因此是一个速度匹配服务,即发送方的发送速率与接收方应用程序的读取速率相匹配。
UDP不提供流量控制
3.5.6 TCP连接管理
客户中的TCP 会用以下方式与服务器中的TCP 建立一条TCP 连接:
笫一步: 客户端的TCP 首先向服务器端的TCP 发送一个特殊的TCP 报文段。该报文段中不包含应用层数据。但是在报文段的首部(参见图3-29) 中的一个标志位(即SYN 比特)被置为1 。因此,这个特殊报文段被称为SYN 报文段。另外,客户会随机地选择一个初始序号(client_isn) , 并将此编号放置千该起始的TCP SYN报文段的序号字段中。该报文段会被封装在一个IP 数据报中,并发送给服务器。
第二步: 一旦包含TCP SYN 报文段的IP 数据报到达服务器主机(假定它的确到达了),服务器会从该数据报中提取出TCP SYN 报文段,为该TCP 连接分配TCP 缓存和变量,并向该客户TCP 发送允许连接的报文段。这个允许连接的报文段也不包含应用层数据。但是,在报文段的首部却包含3 个重要的信息。首先, SYN 比特被置为1 。其次`该TCP 报文段首部的确认号字段被置为client_isn + I 。最后,服务器选择自己的初始序号(server_isn) , 并将其放置到TCP 报文段首部的序号字段中。这个允许连接的报文段实际上表明了: “我收到了你发起建立连接的SYN 分组,该分组带有初始序号client_isn 。我同意建立该连接。我自己的初始序号是server_isn 。”该允许连接的报文段被称为SYNACK 报文段(SYNACK segment) 。
第三步: 在收到SYNACK 报文段后,客户也要给该连接分配缓存和变量。客户主机则向服务器发送另外一个报文段;这最后一个报文段对服务器的允许连接的报文段进行了确认(该客户通过将值server_isn + 1 放置到TCP 报文段首部的确认字段中来完成此项工作) 。因为连接巳经建立了,所以该SYN 比特被置为0 。该三次握手的第三个阶段可以在报文段负载中携带客户到服务器的数据。
注意到为了创建该连接,在两台主机之间发送了3 个分组, 如图3-39 所示。由千这个原因,这种连接创建过程通常被称为3次握手( three-way handshake)。

一条TCP 连接的断开过程:
客户端发送关闭连接命令。客户TCP向服务器进程发送一个特殊的TCP报文段。这个特殊的报文段让其首部中的一个标志位即FIN比特被设置为1.
服务器接收到该报文段,向发送方回送一个确认报文段。然后,服务器发送它自己的终止报文段,其FIN比特被置为1。
最后,该客户对这个服务器的终止报文段进行确认。连接所用的所用资源被释放掉了。



3.6 拥塞
3.6.1 拥塞原因与代价
拥塞网络的一种代价:当分组的到达速率接近链路容量时,分组经历巨大的排队时延。
另一种代价:当一个分组沿一条路径被丢弃时,每个上游路由器用于转发该分组到丢弃该分组而使用的传输容量最终被浪费掉了。
3.6.2 拥塞控制方法
端到端拥塞控制
网络辅助的拥塞控制
默认因特网版本的IP和TCP采用端到端拥塞控制方法。

直接反馈信息可以由网络路由器发给发送方。
路由器标记或更新从发送方流向接收方的分组中的某个字段来指示拥塞的产生。
3.7 TCP拥塞控制
TCP必须使用端到端拥塞控制而不是使网络辅助的拥塞控制,因为IP层不向端系统提供显式的网络拥塞反馈。
TCP 所采用的方法是让每一个发送方根据所感知到的网络拥塞程度来限制其能向连接发送流量的速率。如果一个TCP 发送方感知从它到目的地之间的路径上没什么拥塞, 则TCP 发送方增加其发送速率;如果发送方感知沿着该路径有拥塞, 则发送方就会降低其发送速率
问题一:TCP发送方是如何限制向其连接发送流量的?
问题二:TCP 发送方是如何感知在它与目的地之间的路径上出现了拥塞的?
问题三:TCP 发送方怎样确定它应当发送的速率呢?
一个丢失的报文段表意味着拥塞,因此当丢失报文段时应当降低TCP 发送方的
速率~
·一个确认报文段指示该网络正在向接收方交付发送方的报文段,因此,当对先前
未确认报文段的确认到达时,能够增加发送方的速率。
· 带宽探测
TCP拥塞控制策略
慢启动
在慢启动状态,cwnd的值以1个MSS开始并且每当传输的报文段首次被确认就增加1个MSS。因此, TCP发送速率起始慢,但在慢启动阶段以指数增长。


拥塞避免
快速恢复
TCP拥塞控制:回顾
ACK:确认字符
RTT(Round—Tip Time):往返时间
RWND:滑动窗口
cwnd:拥塞窗口
MSS:最大报文长度
TCP的拥塞控制是:每个RTT内cwnd线性(加性)增加1MSS,然后出现3个冗余ACK事件时cwnd减半(乘性减)。TCP 拥塞控制常常被称为 加性 增、乘性减(Additive-Increase. Multiplicative- Decreasf' ~ A IMO) 拥塞控制方式。
4.网络层:数据平面
4.1 网络层概述

网络层的作用:1.转发 2. 路由选择

转发是由网络层的数据平面执行的主要功能。
路由选择算法决定了插入该路由器转发表的内容。
4.1.2 网络服务模型

4.2 路由器工作原理

路由器的输入端口、输出端口核交换结构几乎总是用硬件实现。
路由器使用转发表来查找输出端口,使得到达的分组能经过交换结构转发到该输出端口。
4.2.2 交换
交换结构使得分组实际地从一个输入端口交换(即转发)到一个输出端口。

交换技术:1.经内存交换;2.经总线交换;3. 经互联网网络交换
4.2.3 输出端口处理
输出端口处理取出已经存放在输出端口内存中的分组并将其发送到输出链路上。
4.2.5 分组调度
即排队的分组如何经输出链路传输的问题。
先进先出

优先权排队

循环和加权公平排队
