《计算机网络——自顶向下方法》 笔记

阅读《计算机网络——自顶向下方法》过程中的笔记,持续更新中。

计算机网络和因特网

什么是因特网

具体构成描述

端系统通过通信链路( communication link)和和分组交换机( packet switch)连接到一 起。

不同的链路能够以不同的速率传输 数据,链路的传输速率以比特/秒度量(bit/s,或bps),当一台端系统要向另一台端系统 发送数据时,发送端系统将数据分段,并为每段加上首部字节。由此形成的信息包用计算 机网络的术语来说称为分组( packet)。

分组交换机从它的一条入通信链路接收到达的分组,并从它的一条出通信链路转发该分组。两种最著 名的类型是路由器( router)和链路层交换机(link- layer switch)。这两种类型的交换机朝 着最终目的地转发分组。链路层交换机通常用于接入网中,而路由器通常用于网络核心 中。

从发送端系统到接收端系统,一个分组所经历的一系列通信链路和分组交换机称为通 过该网络的路径( route或path)。

端系统通过因特网服务提供商( Internet Service Provider,SP)接人因特网,每个ISP是一个由多个分组交换机和多段通信 链路组成的网络。各ISP为端系统提供了各种不同类型的网络接入

端系统、分组交换机和其他因特网部件都要运行一系列协议( protocol),这些协议 控制因特网中信息的接收和发送。TCP( Transmission Control Protocol,传输控制协议) 和IP( Internet Protocol,网际协议)是因特网中两个最为重要的协议。

什么是协议

人类活动类比

enter description here

网络协议

协议定义了在两个或多个通信实体之间交换的报文格式和次序,以及报文发送和/或接收一条报文或其他事件所采取的动作。

网络边缘

通常把与因特网相连的计算机和其他设备称为端系 统。如图1-3所示,因为它们位于因特网的边缘,故而被称为端端系统。

网络核心

网络核心,即由互联因特网端系统的分组交换机链路构成的网状网络

分组交换

在各种网络应用中,端系统彼此交换报文( message)。为了从源端系统向目 的端系统发送一个报文,源将长报文划分为较小的数据块,称之为分组( packet)。在源和 目的之间,每个分组都通过通信链路和分组交换机( packet switch)(交换机主要有两类 路由器和链路层交换机)传送。

存储转发传输

多数分组交换机在链路的输入端使用存储转发传输( store-and- forward transmission )机制。存储转发机制是指在交换机能够开始向输出链路传输该分组的第一个比特之前,必 须接收到整个分组。

enter description here

排队时延和分组丢失

每个分组交换机有多条链路与之相连。对于每条相连的链路,该分组交换机具有一个 输出缓存( output buffer)(也称为输出队列 output queue),它用用于存储路由器准备发往那 条链路的分组。该输出缓存在分组交换中起着重要的作用。如果到达的分组需要传输到某 条链路,但发现该链路正忙于传输其他分组,该到达分组必须在该输出缓存中等待。

除了存储转发时延之外,分组还要承受输出缓存的排队时延(queue delay)

一个到达的分组可能发现该缓存已被其他等待传输的分组完全充满了。在此情况下,将出现分组丢失(丢包)( packet lost),到达的分组或已经排队的分组之一将被丢弃。

转发表和路由选择协议

每台路由器具有一个转发表 ( forwarding table),用于将目的地址(或目的地址的一部分)映射成为输出链路。

电路交换

在电路交换网络中,在端系统间通信会话期间,预留了端系统间通信沿路径所需要的 资源(缓存,链路传输速率)。在分组交换网络中,这些资源则不是预留的;会话的报文 按需使用这些资源,其后果可能是不得不等待(即 排队)接入通信线路。

电路交换网络中的复用

链路中的电路是通过频分复用( Frequency- Division Multiplexing,FDM)或时分复用 (Time- Division Multiplexing,TDM)来实现的。

enter description here

分组交换网中的时延、丢包和吞吐量

时延

时延类型

处理时延+排队时延+传输时延+传播时延

计算机网络中的吞吐量

在任何时间瞬间 的瞬时吞吐量( instantaneous throughput)是主机B接收到该文件的速率(以bps计)。

如果该文件由F比特组成,主机B接收到所有F比特用去T秒,则 文件传送的平均吞吐量( average throughput)是F/Tbps。

协议层次及其服务模型

协议分层

enter description here

面对攻击的网络

利用网络将有害程序放入你的计算机中

今天的多数恶意软件是自我复制(self- replicating)的:一旦它感染了一台主机,就会 从那台主机寻求进入更多的主机。

病毒(virus)是一种需要某种形式的用户交 互来感染用户设备的恶意软件。

蠕虫(worm)是一种无需任何明显用户交互就能进 入设备的恶意软件。

攻击服务器和网络的基础设施

另一种宽泛类型的安全性威胁称为拒绝服务攻击( Denial-of- Service(DoS) attack)。 顾名思义,DoS攻击使得网络、主机或其他基础设施部分不能由合法用户所使用。

大多数DOS攻击属于下列三种类型之一:

  • 弱点攻击
  • 带宽洪泛
  • 连接洪泛

分布式DoS( Distributed Dos,DDoS)中,攻击者 控制多个源并让每个源向目标猛烈发送流量。使用这种方法,为了削弱或损坏服务器,遍 及所有受控源的聚合流量速率需要大约R的能力。

嗅探分组

记录每个流经的分组的副本的被动接收机成为分组嗅探器(packer sniffer)


应用层

应用层协议原理

网络核心设备并不在应用层上 起作用,而仅在较低层起作用,特别是位于网络层及下面层次。这种基本设计,也即将应用软件限制在端系统的方法,促进了大量的网络应用程序的迅速研发和部署。

网络应用程序体系结构

应用程序体系结构( application architecture)由应用程序研发者设计, 规定了如何在各种端系统上组织该应用程序。在选择应用用程序体系结构时,应用程序研发 者很可能利用现代网络应用程序中所使用的两种主流体系结构之一:客户-服务器体系结 构对等(P2P)体系结构

在客戶-服务器体系结构( client- server architecture)中,有一个总是打开的主机称为 服务器,它服务于来自许多其他称为客户的的主机的请求。一个经典的例子是Web应用程序。在一个客户-服务器应用中,常常会出现一台单独的服务器主机跟不上它所有客户请 求的情况。例如,一个流行的社交网络站点如果仅有一台服务器来处理所有请求,将很快 变得不堪重负。为此,配备大量主机的数据中心常被用于创建强大的虚拟服务器。

在一个P2P体系结构(P2 2 architecture)中,对位于数据中心的专用服务器有最小 的(或者没有)依赖。相反,应用程序在间断连接的主机对之间使用直接通信,这些 主机对被称为对等方。这些对等方并不为服务提供商所有,相反却为用户控制的桌面机 和膝上机所有,大多数对等方驻留在家庭、大学和办公室。P2P体系结构最引人入胜的特性之一就是他的自扩展性(self-scalability)。

未来P2P应用面临三个主要挑战:

  • ISP友好。大多数住宅ISP(包括DSL和电缆ISP)已经受制于“非对称的”带宽 应用,也就是说,下载比上载要多得多。但是P2P视频流和文件分发应用改变了 从服务器到住宅ISP的上载流量,因而给ISP带来了巨大压力。
  • 安全性。因为它们的高度分布和开放特性,P2P应用给安全带来挑战
  • 激励。未来P2P应用的成功也取决于说服用户自愿向应用提供带宽、存储和计算 资源,这对激励设计带来挑战

进程通信

在操作系统的术语中,进行通信的实际上是进程( process)而不是程 序。一个进程可以被认为是运行在端系统中的一个程序。

在两个不同端系统上的进程,通过跨越计算机网络交换报文( message)而相互通信。 发送进程生成并向网络中发送报文;接收进程接收这些报文并可能通过将报文发送回去进 行响应。

客户和服务器进程

对每对通信进程, 我们通常将这两个进程之一标识为客户( cient),而另一个进程标识为服务器( server) 。

在P2P文件共享的某些应用中,一个进程能够既是客户又是服 务器。在P2P文件共享系统中,一个进程的确既能上载文件又能下载文件。

进程与计算机网络之间的接口

多数应用程序是由通信进程对组成,每对中的两个进程互相发送报文。从 一个进程向另一个进程发送的报文必须通过下面的网络。进程通过一个称为套接字( socket) 的软件接口向网络发送报文和从网络接收报文。

由于该套接字是建立网络应用程序的可编程接口,因此套接字也 称为应用程序和网络之间的应用程序编程接口( Application Programming Interface,API)。

进程寻址

为了标识接受进程,需要两种信息:主机地址;定义在目的主机中的接收进程的标识符

在因特网中,主机由其IP地址标识,端口号用于标识后者。

enter description here

可供应用程序使用的运输服务

可靠数据传输

需要可靠数据传输的应用,必须做一些工作以确保由应用程序的一端发送的数据正确、完全地交付给该应用程序的另一端 ,如果一个协议提供了这样的确保数据交付服务,就认为提供了可靠数据传输( reliable data transfer)。

当一个运输层协议不提供可靠数据传输时,由发送进程发送的某些数据可能不能够到 达接收进程。这可能能被容忍丢失的应用(los- tolerant application)所接受,最值得注意 的是多媒体应用,如交谈式音频/视频,它们能够承受一定量的数据丢失。

吞吐量

具有吞吐量要求的应用程序被称为 带宽敏感的应用( bandwidth- sensitive application)。许多当前的多媒体应用是带宽敏感的 尽管某些多媒体应用程序可能采用自适应编码技术对数字语音或视频以与当前可用带宽相 匹配的速率进行编码。

带宽敏感的应用具有特定的吞吐量要求,而而弹性应用( elastic application)能够根据 情况或多或少地利用可供使用的吞吐量。

定时

运输层协议能提供定时保证,

安全性

运输协议能够为应用程序提供一种或者多种安全性服务

因特网提供的运输服务

因特网(更一般的是TCP/P网络络)为应用程序 提供两个运输层协议,即UDP和TCP。

enter description here

TCP服务

TCP服务模型包括面向连接服务和可靠数据传输服务:

  • 面向连接的服务:在应用层层数据报文开始流动之前,TCP让客户和服务器互相交 换运输层控制信息。这条连接是全双工的,即连接双方的进程可以在此连接 上同时进行报文收发。当应用程序结束报文发送时,必须拆除该连接。
  • 可靠的数据传送服务:通信进程能够依靠TCP,无差错、按适当顺序交付所有发 送的数据。

    TCP协议还具有拥塞控制机制,这种服务不一定能为通信进程带来直接好处,但能为 因特网带来整体好处。

TCP 安全

无论TCP还是UDP都没有提供任何加密机制,这就是说发送进程传进其套接字的 数据,与经网络传送到目的进程的数据相同。

因特网界已经经研制了TCP的加强版 本,称称为安全套接字层( Secure Sockets Layer,SSL)。用SSL加强后的TCP不仅能够做 传统的TCP所能做的一切,而且提供了关键的进程到进程的安全性服务,包括加密、数 据完整性和端点鉴别。

UDP 服务

UDP是一种不提供不必要服务的轻量级运输协议,它仅提供最小服务。UDP是无连 接的,因此在两个进程通信前没有握手过程。UDP协议提供一种不可靠数据传送服务,也 就是说,当进程将一个报文发送进UDP套接字时,UDP协议并不保证该报文将到达接收 进程。不仅如此,到达接收进程的报文也可能是乱序到达的。

enter description here

应用层协议

应用层协议( application- layer protocol)定义了运行在不同 端系统上的应用程序进程如何相互传递报文。有些应用层协议是由RFC文档定义的,因此它们位于公共域中。例如,Web的应用

Web和HTTP

Web是一个引起公众注意的因特网应用,它极大地改变了人们与工作环境内外交流的方式。它将因特网从只是很多数据网之一的地位提升为仅有的一个数据网。 也许对大多数用户来说,最具有吸引力的就是Web的按需操作。

HTTP 概况

Web的应用层协议是超文本传输协议( Hypertext Transfer Protocol,HTTP),它是Web 的核心。HTTP由两个程序实现:一个客户程序和一个服务器程序。

HTTP使用TCP作为它的支撑运输协议 (而不是在UDP上运行)。HTTP客户首先发起 个与服务器的TCP连接。

因为HTP服务器并不保存关于客户的任何信息,所 以我们说HTTP是一个无状态协议议( stateless protocol)。

非持续连接和持续连接

每个请求/响应对是经一个单独的TCP连接发送,还是所有的请求及其响应经相同的TCP连接发送 ?采用前一种方法,该应用程序被称为使用非持续连接(non- persistent connection);采用后一种方法,该应用程序被称为使用持续连接( persistent connection)。

HTTP在其默认方式下使用持续连接,HTTP客户和服务器也能配置成使用非持续连接

非持续连接有一些缺点。首先,必须为每一个请求的对象建立和维护一个全新的对于每个这样的连接,在客户和服务器中都要分配TCP的缓冲区和保持TCP变量, 这给Web服务器带来了严重的负担,因为一台Web服务器可能同时服务于数以百计不同 的客户的请求。第二,每一个对象经受两倍RTT的交付时延, 即一个RTT用于创建TCP,另一个RTT用于请求和接收一个对象

在采用持续连接的情况下,服务器在发送响应后保持该TCP连接打开。在相同的客户与服务器之间的后续请求和响应报文能够通过相同的连接进行传送。

HTTP 报文格式

请求报文

enter description here

响应报文

enter description here

用户和服务器的交互:cookie

HTTP服务器是无状态的。这简化了服务器的设计,并且允许工程师 们去开发可以同时处理数以千计的TCP连接的高性能Web服务器。然而一个Web站点通 常希望能够识別用户,可能是因为服务器希望限制用户的访回,或者因为它希望把内容与 用户身份联系起来。为此,HTTP使用了 cookie。 它允许 站点对用户进行跟踪。目前大多数商务Web站点都使用了 cookie。

cookie技术有4个组件:
①在HTTP响应报文中的一个 cookie首部 行;
②在HTTP请求报文中的一个 cookie首部行;
③在用户端系统中保留有一个 cookie文 件,并由用户的测览器进行管理;
④位于Web站点的一个后端数据库。

enter description here

Web缓存

Web缓存器( Web cache)也叫代理服务器( proxy server),它是能够代表 初始Web服务器来满足HTTP请求的网络实体。

enter description here

条件GET方法

HTTP协议有一种机制,允许缓存器证实它的对象是最新的。这种机制就是条件 GET( conditional GET)方法法。如果:①请求报文使用GET方法;并且(②请求报文中包 含一个“If- Modified- Since:”首部行。那么,这个HTTP请求报文就是一个条件GET请 求报文

文件传输协议:FTP

HTTP和FTP都是文件传输协议,并且有很多共同的特点,例如,它们都运行在TCP 上。然而,这两个应用层协议也有一些重要的区别。其中最显著的就是FTP使用了两个并行的TCP连接来传输文件,一个是控制连接( control connection),一个是数据连接(data connecton)。

控制连接用于在两主机之间传输控制信息,如用户标识、口令、改变远程目 录的命令以及“存放(put)”和和“获取(get)”文件的命令。数据据连接用于实际发送一个 文件。因为FTP协议使用一个独立的控制连接,所以我们也称FTP的控制信息是带外 (om-oand)传送的。

FTP服务器必须在整个会话期间保留用户的状态(state)

因特网中的电子邮件

因特网电子邮件系统由3个部分组成:用户代理、邮件服务器和简单邮件传输协议

enter description here

邮件服务器形成了电子邮件体系结构的核心。每个接收方(如Bob)在其中的某个邮 件服务器上有一个邮箱( mailbox)。

SMTP是因特网电子邮件中主要的应用层协议

SMTP

SMTP是因特网电子邮件应用的核心。如前所述, SMTP用于从发送方的邮件服务器发送报文到接收方的邮件服务器。

enter description here

与HTTP对比

这两个协议都用于从一台主机向另一台主机传 送文件:HTTP从Web服务器向Web客户(通常是一个测览器)传送文件(也称为对 象);SMTP从一个邮件服务器向另一个邮件服务器传送文件(即电子邮件报文)。当进行 文件传送时,持续的HTTP和SMTP都使用持续连接。因此,这两个协议有一些共同特征。 然而,两者之间也有一些重要的区别。

首先,HTTP主要是一个拉协议( pull protocol), 即在方便的时候,某些人在Web服务器上装载信息,用户使用HTTP从该服务器拉取这些 信息。特别是TCP连接是由想接收文件的机器发起的。另一方面,SMTP基本上是一个推 协议( push protocol),即发送邮件服务器把文件推向接收邮件服务器。特别是,这个TCP 连接是由要发送该文件的机器发起的。

第二个区别就是我们前面间接地提到过的,SMTP要求每个报文(包括它们的体)使 用7比特ASC2码格式。如果某报文包含了非7比特ASCⅡ字符(如具有重音的法文 符)或二进制数据(如图形文件),则该报文必须按照7比特ASCⅡ码进行编码。HTP数 据则不受这种限制。

第三个重要区别是如何处理一个既包含文本又包含图形(也可能是其他媒体类型)的 文档。HTTP把每个对象封装到它自己的HTP响应报文中 而SMTP则把所有报文对象放在一个报文之中。

邮件访问协议

邮件访问使用了一种客户-服务器体系结构,即典型的用户通过在用户端系统上运行的客户程序来阅读电子邮件。

目前有一些流行的的邮件访问协议,包括第三版的邮局协议( Post Offfice Protocol– Version3,POP3)、因特网邮件访问协议( Internet Mail Access Protocol,IMAP) 以及HTTP。

enter description here

DNS:因特网的目录服务

因特网上的主机和人类一样,可以使用多种方式进行标识。主机的一种标识方法是用它 的主机名( hostname),这些名字便于记忆也乐于被人们接受。然而,主机名几平没有提供,况且,因为主机名可能由不定长的字母数字 组成,路由器难以处理。由于这些原因,主机也可以使用所谓IP地址( IP address)进行

DNS提供的服务

主机名到IP地址转换的目录服务——域名系统 ( Domain Name System,DNS)。

DNS是:

  • ①一个由分层的DNS服务器(DN server)实现的分布式数据库;
  • ②一个使得主机能够査询分布式数据库的应用层协议。

    DNS通常是由其他应用层协议所使用的,包括HTP、SMTP和FTP,将用户提供的主 机名解析为IP地址。

    除了进行主机到IP地址的转换,DNS还提供了一些重要的服务:

    • 主机别名
    • 邮件服务器别名
    • 负载分配

DNS工作原理概述

DNS的一种简单设计是在因特网上只使用一个DNS服务器,该服务器包含所有的映 射。在这种集中式设计中,客户直接将所有查询直接发往单一的DNS服务器,同时该 DNS服务器直接对所有的查询客户做出响应。尽管这种设计的简单性非常具有吸引力,但 它不适用于当今的因特网,因为因特网有着数量巨大(并持续增长)的主机这种集中式 设计的问题包括:

  • 单点故障( a single point of failure),如果该DNS服务器崩溃,整个因特网随之 瘫痪!
  • 通信容量( traffic volume)。单个DNS服务器不得不处理所有的DNS查询(用于为 上亿台主机产生的所有HTTP请求报文和电子邮件报文服务)
  • 远距离的集中式数据库( distant centralized database)。单个DNS服务器不可能 “邻近”所有查询客户。如果我们将单台DNS服务器放在纽约市,那那么所有来自 澳大利亚的查询必须传播到地球的另一边边,中间也许还要经过低速和拥塞的链路。 这将导致严重的时延。
  • 维护( maintenance)。单个DNS服务器将不得不为所有的因特网主机保留记录。

在单一DNS服务器上运行集中式数据库完全没有可扩展能力。因此,DNS采用了分布式的设计方案:

  1. 分布式,层次数据库

为了处理扩展性问题,DNS使用了大量的DNS服务器,它们以层次方式组织,并且 分布在全世界范围内。没有一台DNS服务器拥有因特网上所有主机的映射。相反,该映射分布在所有的DNS服务器上。大致说来,有3种类型的DNS服务器:根DNS服务器、 顶级域DNS服务器和权威DNS服务器

enter description here

DNS查询有递归查询(recursive query)和迭代查询(iterative query)。

  1. DNS缓存

为了改善时延性能并减 少在因特网上到处传输的DNS报文数量 DNS广泛使用了缓存技术。DNS缓存的原 理非常简单。在一个请求链中,当某DNS服务器接收一个DNS回答(例如,包含主 机名到IP地址的映射)时,它能将该回答 中的信息缓存在本地存储器中

由于主机和IP之间的映射并不是永久的,DNS服务器在一段时间将丢弃缓存信息。

DNS记录和报文

共同实现DNS分布式数据库的所有DNS服务器存储了资源记录( Resource Record, RR),RR提供了主机名到IP地址的映射。每个DNS回答报文包含了一条或多条资源记 录。

资源记录是一个包含了下列字段的4元组:(Name, Value, Type, TTL)

TTL是该记录的生存时间,它决定了资源记录应当从缓存中删除的时间。

Name和 Value的值取决于Type:

  • 如果Type=A,则Name是主机名, Value是该主机名对应的P地址。因此,一条类型为A的资源记录提供了标准的主机名到IP地址的映射。
  • 如果Type=NS,则Name是个域(如foo.com),而Vaue是个知道如何获得该域中主机IP地址的权威DNS服务器的主机名。
  • 如果Type= CNAME,则 Value是别名为Name的主机对应的规范主机名。该记录 能够向查询的主机提供一个主机名对应的规范主机名
  • 如果Type=MX,则 Value是个别名为Name的邮件服务器的规范主机名。

DNS 报文

enter description here

P2P应用

使用P2P体系结 构,对总是打开的基础设施服务器有最小的的(或者没有)依赖。与之相反,成对间歇连接 的主机(称为对等方)彼此直接通信。这些对等方并不为服务提供商所拥有,而是受用户 控制的桌面计算机和膝上计算机

P2P文件分发

在客户-服务器文件分发中,该服务器必须向每个对等方发送该文件的一个副本,即服务 器承受了极大的负担,并且消消耗了大量的服务器带宽。在P2P文件分发中,每个对等方能 够重新分发它所有的该文件的任何部分,从而在分发过程程中协助该服务器。

到2012年止, 最为流行的P2P文件共享协议是 Bit Torrent。

P2P体系结构的扩展性

enter description here

enter description here

BitTorrent

Bit Torrent是一种用于文件分发的流行P2P协议。用 Bittorrent的术语来 讲,参与一个特定文件分发的所有对等方的集合被称为一个洪流( torrent)。在一个洪流 中的对等方彼此下载等长度的文件块( chunk),典型的块长度为256KB。当一个对等方首次加入一个洪流时,它没有块。随着时间的流逝,它累积了越来越多的块。当它下载块 时,也为其他对等方上载了多个块。一旦某对等方获得了整个文件,它也许(自私地)离 开洪流,或(大公无私地)留在该洪流中并继续向其他对等方上载块。

每个洪流具有一个基础设施结点,称为追踪器( tracker)。当一个对等方加入 某洪流时,它向追踪器注册自己,并周期性地通知追踪器它仍在该洪流中。以这种方式, 追踪器跟踪正参与在洪流中的对等方。

对等方会周期性的询问每个邻近的对等方他们所具有的块列表。同时还要解决一些问题:第一,她应当从她的邻居请求哪些块呢?第二,她 应当向哪些向她请求块的邻居发送?

在决定请求哪些块的过程中,每一个对等方使用一种称为最稀缺优先( rarest first)的技术。这种技术的思路是,针对她没有的块在她的邻居中决定最 稀缺的块(最稀缺的块就是那些在她的邻居中副本数量最少的块),并首先请求那些最稀 缺的块。这样,最稀缺块得到更为迅速的重新分发,其目标是(大致地)均衡每个块在洪流中的副本数量。

TCP 套接字编程

UDP套接字编程

发送进程为分组附上的目的地址是由目的主机的IP地址和目的套接字的端口号组成。

发送方的源地址也是由源主机的IP地址和源套接字的端口号组成

示例程序:

enter description here

UDPclient.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 引入socket包,python网络通信的基础
from socket import *

# 提供IP地址(域名)和端口号
serverName = 'hostname'
serverPort = 12000

# 创建客户套接字,AF_INET表示底层网络使用IPv4,SOCK_DGRAM表示为UDP套接字
clientSocket = socket(AF_INET, SOCK_DGRAM)
message = raw_input('Input lowercase sentence')

# 向目的套接字发送
clientSocket.sendto(message,(serverName,serverPort))

# 接收分组,取2048作为缓存输入
modifiedMessage, serverAddress = clientSocket.recvform(2048)

print(modifiedMessage)
clientSocket.close()

UDPserver.py

1
2
3
4
5
6
7
8
9
10
11
12
13
from socket import *

serverPort = 12000
serverSocket = socket(AF_INET, SOCK_DGRAM)

# 将服务器端口和套接字绑定在一起
serverSocket.bind('', serverPort)

print("The server is ready to receive")
while ture:
message, clientAddress = serverSocket.recvform(2048)
modifiedMessage = message.upper()
serverSocket.sendto(modifiedMessage, clientAddress)

TCP套接字编程

与UDP不同,TCP是一个面向连接的协议。这意味着客户和服务器能够相互发送数据之前,他们要先握手创建一个TCP连接。

注意两点:
第一,与在UDP中的情况一样,TCP服务器在客户试图发起接触前必须作 为进程运行起来。
第二,服务器程序必须具有一扇特殊的门,更精确地说是一个特殊的套 接字,该门门欢迎来自运行在任意主机上的客户进程的某些初始接触。使用房子/门来比喻 进程/套接字,有时我们将客户的初始接触称为“敲欢迎之门”。

enter description here

enter description here

TCPclient.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from socket import *

serverName = 'servername'
serverPort = 12000

clientSocket = socket(AF_INET, SOCK_STREAM)
# 不同之处,传输数据之前要先进行连接
clientSocket.connect((serverName, serverPort))

sentence = raw_input('Input lowercase sentence')
clientSocket.send(sentence)
modifiedSentence = clientSocket.recv(1024)

print("From server:", modifiedSentence)
clientSocket.close()

TCPserver.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from socket import *

serverPort = 12000
# 创建TCP套接字
serverSocket = socket(AF_INET, SOCK_STREAM)

# serverSocket 是我们的欢迎套接字
serverSocket.bind('', serverPort)
serverSocket.lisetn(1)
print("The server is ready to receive")

while ture:
# 当客户端敲门时,创建一个服务的新套接字
connectionSocket ,addr = serverSocket.accept()
sentence = connectionSocket.recv(1024)
capitalizedSentence = sentence.upper()
connectionSocket.sendto(capitalizedSentence)
connectionSocket.close()

运输层

概述和运输层服务

运输层协议为运行在不同主机上的应用进程之间提供了逻辑通信( logic communication)功能。从应用程序的角度看,通过逻辑通信,运行不同进程的主机好像直接相连一样;实际上,这些主机也许位于地球的两侧,通过很多路由器及多种不同类型的链路相连。

运输层和网络层之间的关系

前面讲过,在协议栈中,运输层刚好位于网络层之上。网络层提供了主机之间的逻辑通信,而运输层为运行在不同主机上的进程之间提供了逻辑通信。

因特网运输层概述

前面讲过因特网(更一般地讲是一个TCP/IP网络)为应用层提供了两种截然不同的可用运输层协议。这些协议一种是UDP(用户数据报协议),它为调用它的应用程序提供了一种不可靠、无连接的服务。另一种是TCP(传输控制协议),它为调用它的应用程序提供了一种可靠的、面向连接的服务。当设计一个网络应用程序时,该应用程序的开发人员必须指定使用这两种运输协议中的哪一种。

有些文献中将TCP的运输层分组成为报文段,而讲UDP的分组称为数据报

UDP和TCP最基本的责任是,将两个端系统间IP的交付服务扩展为运行在端系统上的两个进程之间的交付服务。将主机间交付扩展到进程间交付被称为运输层的多路复用(transport-layer multiplexing)与多路分解( demultiplexing)

TCP为应用程序提供了几种附加服务。首先,它提供可靠数据传输(reliable data transfer)。通过使用流量控制、序号、确认和定时器,TCP确保正确地、按序地将数据从发送进程交付给接收进程。这样,TCP就将两个端系统间的不可靠IP服务转换成了一种进程间的可靠数据传输服务。TCP还提供拥塞控制( congestion control)。拥塞控制与其说是一种提供给调用它的应用程序的服务,不如说是一种提供给整个因特网的服务,这是一种带来通用好处的服务。

多路复用与多路分解

我们考虑接收主机怎样将一个到达的运输层报文段定向到适当的套接字。为此目的,每个运输层报文段中具有几个字段。在接收端,运输层检查这些字段,标识出接收套接字,进而将报文段定向到该套接字。将运输层报文段中的数据交付到正确的套接字的工作称为多路分解( demultiplexing)。

在源主机从不同套接字中收集数据块,并为每个数据块封装上首部信息(这将在以后用于分解)从而生成报文段,然后将报文段传递到网络层,所有这些工作称为多路复用( multiplexing)。

无连接运输:UDP

有的时候我们需要将上层交给运输层的数据直接交付给下面的网络层,运输层最低限度必须提供一种复用/分解服务,以便在网络层与正确的应用级进程之间传递数据。事实上UDP只是做了运输层协议能够做的最少的事情。

如果应用程序开发人员选择UDP而不是TCP,则该应用程序差不多就是直接与I打交道。

DNS服务就是一个运用咋UDP上的一个应用层的例子,很明显,有些应用更加适用于UDP,原因主要有以下几点:

  • 关于何时、发送什么数据的应用层控制更为精细
  • 无需建立连接,这样就不会引入连接的时延,这样就能够达到更快的速度
  • 无连接状态。相比而言,TCP需要在端系统中维护连接状态。此连接状态包括接收和发送缓存、拥塞控制参数以及序号与确认号的参数。所以对数据的利用率将会更高
  • 分组首部开销小。每个TCP报文段都有20字节的首部开销,而UDP仅有8字节的开销。

使用UDP也可以进行可靠的数据传输,只不过需要在上层自己进行协议的制定。

UDP报文段结构

UDP检验和

UDP检验和提供了差错检测功能。发送方的UDP对报文段中的所有16比特字的和进行反码运算,求和时遇到的任何溢出都被回卷。得到的结果被放在UDP报文段中的检验和字段。(所有比特字进行求和然后取反码)

可靠数据传输原理

可靠数据传输这个需求不仅仅在传输层需要,在链路层和应用层同样也需要。

通过可靠数据传输我们要做到的是:传输的数据比特不会受到损坏或者丢失,所有顺序都是按照发送的顺序进行交付的。

构造可靠数据传输协议

经完全可靠信道的可靠数据传输: rdt1.0

考虑最简单的情况,底层的通信是完全可靠的,这个时候就非常简单了。

经具有比特差错信道的可靠数据传输: rdt2.0

底层信道更为实际的模型是分组中的比特可能受损。一般情况下,接收方在接到可能出错的数据的时候使用到的是肯定确认(ACK)或者否定确认(NAK)的机制。这些控制报文使得接收方可以让发送方知道哪些内容被正确接收,哪些内容接收有误并因此需要重复。在计算机网络环境中,基于这样重传机制的可靠数据传输协议称为自动重传请求(ARQ)协议

ARQ协议还需要另外三种协议来一起协同处理比特差错的情况:

  • 差错检测
  • 接受方反馈,接收方发现差错以后要想发送方进行反馈
  • 重传,发送方重传有错误的分组

rdt2.0协议看起来似乎可以运行了,但遗憾的是,它存在一个致命的缺陷。尤其是我们没有考虑到ACK或NAK分组受损的可能性!

考虑到处理ACK或NAK分组受损的3种可能:

  1. 收到受损的信息以后,返回信息表示信息受损,但是这个返回的信息也可能受损,这样就出现了死循环
  2. 增强差错编码,不仅仅能检查错误还能够修复错误,这种情况只能解决只会产生差错不会丢失分组的信道中
  3. 第三种方法是,当发送方收到含糊不清的ACK或NAK分组时,只需重传当前数据分组即可。但是这种方法会导致接受方不知道重传的分组是新的还是重传的

解决这个新问题的一个简单方法(几乎所有现有的数据传输协议中,包括TCP,都采用了这种方法)是在数据分组中添加一新字段,让发送方对其数据分组编号,即将发送数据分组的序号(sequence number)放在该字段。于是,接收方只需要检查序号即可确定收到的分组是否一次重传。(通过给分组添加需要判断新的分组是否是重传过来的分组)

经具有比特差错的丢包信道的可靠数据传输: rdt3.0

现在假定除了比特受损外,底层信道还会丢包,这在今天的计算机网络(包括因特网)中并不罕见。协议现在必须处理另外两个关注的问题:怎样检测丢包以及发生丢包后如何进行处理

有很多可能的方法用于解决丢包问题。这里,我们让发送方负责检测和恢复丢包工作。假定发送方传输一个数据分组,该分组或者接收方对该分组的ACK发生了丢失。在这两种情况下,发送方都收不到应当到来的接收方的响应。如果发送方愿意等待足够长的时间以便确定分组已丢失,则它只需重传该数据分组即可。

我们需要确定的是这个等待时间需要多长?一种方案是使用最坏情况下的最大时延,但是在很多网络中,最坏情况下的最大时延是很难估算的,确定的因素非常少。因此另外一种方案是发送方明智的选择一个比较少的时间,用来判断可能发生了丢包,这种情况下可能产生冗余数据分组,不过rdt2.2已经能够通过序号的方案对这种情况进行处理

流水线可靠数据传输协议

rdt3.0是一个功能正确的协议,但是它的性能不是很让人满意,这个性能的核心问题在于它是一个停等协议。

解决这种特殊的性能问题的一个简单方法是:不使用停等方式运行,允许发送方发送多个分组而无需等待确认。如果发送方可以在等待确认之前发送3个报文,其利用率也基本上提高3倍。因为许多从发送方向接收方输送的分组可以被看成是填充到一条流水线中,故这种技术被称为流水线(pipelining)。

流水线技术对可靠数据传输协议可带来如下影响

  • 必须增加序号范围,每个输送中的分组必须有唯一的一个序号
  • 协议的发送方和接受方必须缓存多个分组
  • 所需序号范围和对缓冲的要求取决于数据传输协议如何处理丢失、损坏及延时过大的分组。解决流水线的差错恢复有两种基本方法是:回退N步(Go-Back-NGBN)和选择重传( Selective Repeat,SR)

回退N步

在回退N步(GBN)协议中,允许发送方发送多个分组(当有多个分组可用时)而不需等待确认,但它也受限于在流水线中未确认的分组数不能超过某个最大允许数N。

发送方的数据可以划分成4类:已经发送并且已经确认的分组、发送了但是未确认的分组、分配需要即将被发送的分组和没有分配序号的将要发送的分组。

那些已被发送但还未被确认的分组的许可序号范围可以被看成是一个在序号范围内长度为N的窗口。随着协议的运行,该窗口在序号空间向前滑动。因此,N常被称为窗口长度( window size),GBN协议也常被称为滑动窗口协议(sliding- window protocol)。限制长度的原因是为了流量控制和拥塞控制

GBN发送方必须响应三种类型的事件:

  1. 上层的调用
  2. 收到一个ACK。在GBN协议中,对序号为n的分组的确认采取累积确认(cumlative acknowledgment)的方式,表明接收方已正确接收到序号为n的以前且包括n在内的所有分组。
  3. 超时事件。协议的名字“回退N步”来源于出现丢失和时延过长分组时发送方的行为。如果出现超时,发送方重传所有已发送但还未被确认过的分组。

在GBN协议中,接收方丢弃所有失序分组。尽管丢弃一个正确接收(但失序)的分组有点愚蠢和浪费,但这样做是有理由的。因为数据必须按序交付,接收方可能缓存(保存)分组n+1,然后,在它收到并交付分组n后,再将该分组交付到上层。如果一个分组出现问题,其后面的分组一定都会重传。所以不需要担心这个浪费。

选择重传

GBN协议潜在地允许发送方用多个分组“填充流水线”,因此避免了停等协议中所提到的信道利用率问题。然而,GBN本身也有一些情况存在着性能问题。尤其是当窗口长度和带宽时延积都很大时,在流水线中会有很多分组更是如此。单个分组的差错会导致GBN重传大量分组

顾名思义,选择重传(SR)协议通过让发送方仅重传那些它怀疑在接收方出错(即丢失或受损)的分组而避免了不必要的重传。这种个别的、按需的重传要求接收方逐个地确认正确接收的分组。再次用窗口长度N来限制流水线中未完成、未被确认的分组数。

发送方做的事情:

  • 从上层接受数据
  • 超时,定时器再次被用来防止丢失分组。然而,现在每个分组必须拥有其自己的逻辑定时扌器,因为超时发生后只能发送一个分组。
  • 收到ACK,如果收到ACK,倘若该分组序号在窗口内,则SR发送方将那个被确认的分组标记为已接收。如果该分组的序号等于 send base,则窗口基序号向前移动到具有最小序号的未确认分组处。

SR接收方将确认一个正确接收的分组而不管其是否按序。失序的分组将被缓存直到所有丢失分组(即序号更小的分组)皆被收到为止,这时才可以将一批分组按序交付给上层。

面向连接的运输:TCP

TCP连接

TCP被称为是面向连接的( connection- oriented),这是因为在一个应用进程可以开始向另一个应用进程发送数据之前,这两个进程必须先相互“握手”,即它们必须相互发送某些预备报文段,以建立确保数据传输的参数

TCP连接提供的是全双工服务(full-duplex service):如果一台主机上的进程A与另台主机上的进程B存在一条TCP连接,那么应用层数据就可在从进程B流向进程A的同时,也从进程A流向进程B。TCP连接也总是点对点( point-to-point)的,即在单个发送方与单个接收方之间的连接。所谓“多播”,即在一次发送操作中,从个发送方将数据传送给多个接收方,对TCP来说这是不可能的。对于TCP而言,两台主机是一对,而3台主机则太多!

TCP可从缓存中取出并放入报文段中的数据数量受限于最大报文段长度( Maximum Segment Size,MSS)。MSS通常根据最初确定的由本地发送主机发送的最大链路层帧长度(即所谓的最大传输单元( Maximum transmissionUnit,MTU))来设置。

TCP为每块客户数据配上一个TCP首部,从而形成多个TCP报文段

TCP报文段结构

TCP报文段由首部字段和数据字段组成,数据字段包含的是上层的应用数据。当TCP发送一个大文件时候,会将文件拆分成长度为MSS的若干块。

上图显示了TCP报文段的结构。与UDP一样,首部包括源端口号和目的端口号,它被用于多路复用/分解来自或送到上层应用的数据。另外,同UDP一样,TCP首部也包括检验和字段( checksum field)

TCP首部还包含以下字段:

  • 32比特的序号字段和32比特的确认号字段,用于实现可靠数据传输
  • 16比特的接收窗口字段,该字段用于流量控制
  • 4比特的首部长度字段,该字段指示了以32比特的字为单位的TCP首部长度。
  • 可选与变长的选项字段,该字段用于发送方与接收方协商最大报文段长度(MSS)时,或在高速网络环境下用作窗口调节因子时使用。
  • 6比特的标志字段(flag field)。ACK比特用于指示确认字段中的值是有效的,即该报文段包括一个对已被成功接收报文段的确认。RST、SYN和FIN比特用于连接建立和拆除。当PSH比特被设置的时候,就指示接收方应立即将数据交给上层。最后,URG比特用来指示报文段里存在着被发送端的上层实体置为“紧急”的数据。紧急数据的最后一个字节由16比特的紧急数据指针字段指出。当紧急数据存在并给出指向紧急数据尾的指针的时候,TCP必须通知接收端的上层实体。

序号和确认号

一个报文段的序号因此是该报文段首字节的字节流编号。TCP采取的是累计确认的机制,发送一个确认号码表示这个序号之前的报文段都收到了

对于失序的报文段有两个选择:①接收方立即丢弃失序报文段(如前所述,这可以简化接收方的设计);②接收方保留失序予的字节,并等待缺少的字节以填补该间隔。后面一种对网络带宽更加有效,所以也应用于实践中。

往返时间估计与超时

TCP采用超时/重传机制来处理报文段的丢失问题。显然,超时间隔必须大于该连接的往返时间(RTT),即从一个报文段发出到它被确认的时间。否则会造成不必要的重传。

TCP是如何估计发送方与接收方之间往返时间的。这是通过如下方法完成的。报文段的样本RTT(表示为 Samplertt)就是从某报文段被发出(即交给IP)到对该报文段的确认被收到之间的时间量。

可靠数据传输

TCP在IP不可靠的尽力而为服务之上创建了一种可靠数据传输服务( reliable datatransfer service)。TCP的可靠数据传输服务确保一个进程从其接收缓存中读出的数据流是无损坏、无间隔、非冗余和按序的数据流;即该字节流与连接的另一方端系统发送出的字节流是完全相同。

TCP发送方主要处理3个事件:

  1. 从上层应用程序接受数据,将数据封装到一个报文段中,然后交给IP,同时启动定时器
  2. 定时器超时,TCP通过重传引起超时的报文段来响应超时事件。然后重启定时器
  3. 接受到来自接收方的确认报文段(ACK),TCP采用累积确认

流量控制

一条TCP连接每一侧主机都为该连接设置了接收缓存。当该TCP连接收到正确、按序的字节后,它就将数据放入接收缓存。相关联的应用进程会从该缓存中读取数据,但不必是数据刚一到达就立即读取。

TCP为它的应用程序提供了流量控制服务(flow-control service)以消除发送方使接收方缓存溢出的可能性。流量控制因此是一个速度匹配服务,即发送方的发送速率与接收方应用程序的读取速率相匹配。

TCP通过让发送方维护一个称为接收窗口( receive window)的变量来提供流量控制通俗地说,接收窗口用于给发送方一个指示—该接收方还有多少可用的缓存空间。因为TCP是全双工通信,在连接两端的发送方都各自维护一个接收窗口。

TCP连接管理

TCP建立连接的三次握手:

三次握手的原因:

第三次握手是为了防止失效的连接请求到达服务器,让服务器错误打开连接。

失效的连接请求是指,客户端发送的连接请求在网络中滞留,客户端因为没及时收到服务器端发送的连接确认,因此就重新发送了连接请求。滞留的连接请求并不是丢失,之后还是会到达服务器。如果不进行第三次握手,那么服务器会误认为客户端重新请求连接,然后打开了连接。但是并不是客户端真正打开这个连接,因此客户端不会给服务器发送数据,这个连接就白白浪费了。

TCP断开连接的四次挥手:

四次挥手的原因:

客户端发送了 FIN 连接释放报文之后,服务器收到了这个报文,就进入了 CLOSE-WAIT 状态。这个状态是为了让服务器端发送还未传送完毕的数据,传送完毕之后,服务器会发送 FIN 连接释放报文。

TIME_WAIT

客户端接收到服务器端的 FIN 报文后进入此状态,此时并不是直接进入 CLOSED 状态,还需要等待一个时间计时器设置的时间 2MSL。这么做有两个理由:

确保最后一个确认报文段能够到达。如果 B 没收到 A 发送来的确认报文段,那么就会重新发送连接释放请求报文段,A 等待一段时间就是为了处理这种情况的发生。

等待一段时间是为了让本连接持续时间内所产生的所有报文段都从网络中消失,使得下一个新的连接不会出现旧的连接请求报文段。

TCP 拥塞控制

如果网络出现拥塞,分组将会丢失,此时发送方会继续重传,从而导致网络拥塞程度更高。因此当出现拥塞时,应当控制发送方的速率。这一点和流量控制很像,但是出发点不同。流量控制是为了让接收方能来得及接受,而拥塞控制是为了降低整个网络的拥塞程度。

TCP 主要通过四种算法来进行拥塞控制:慢开始、拥塞避免、快重传、快恢复。发送方需要维护一个叫做拥塞窗口(cwnd)的状态变量。注意拥塞窗口与发送方窗口的区别,拥塞窗口只是一个状态变量,实际决定发送方能发送多少数据的是发送方窗口。

慢开始与拥塞避免

发送的最初执行慢开始,令 cwnd=1,发送方只能发送 1 个报文段;当收到确认后,将 cwnd 加倍,因此之后发送方能够发送的报文段数量为:2、4、8 …

注意到慢开始每个轮次都将 cwnd 加倍,这样会让 cwnd 增长速度非常快,从而使得发送方发送的速度增长速度过快,网络拥塞的可能也就更高。设置一个慢开始门限 ssthresh,当 cwnd >= ssthresh 时,进入拥塞避免,每个轮次只将 cwnd 加 1。

如果出现了超时,则令 ssthresh = cwnd/2,然后重新执行慢开始。

快重传与快恢复

在接收方,要求每次接收到报文段都应该发送对已收到有序报文段的确认,例如已经接收到 M1 和 M2,此时收到 M4,应当发送对 M2 的确认。

在发送方,如果收到三个重复确认,那么可以确认下一个报文段丢失,例如收到三个 M2 ,则 M3 丢失。此时执行快重传,立即重传下一个报文段。

在这种情况下,只是丢失个别报文段,而不是网络拥塞,因此执行快恢复,令 ssthresh = cwnd/2 ,cwnd = ssthresh,注意到此时直接进入拥塞避免。


#