第58章 SOCKET:TCP/IP网络基础

58.1 互联网

      互联网会将不同的计算机网络连接起来并允许位于网络中的主机相互之间进行通信。换句话说,一个互联网是由计算机网络组成的一个网络。互联网的目标是隐藏不同物理网络的细节以便向互联网中的所有主句呈现一个统一的网络架构,例如,这意味着可以使用单个地址格式来标识互联网上的所有主机。

        尽管已经设计除了多种互联网互联协议,但TCP/IP已经成了使用最为广泛的协议套件了,

他甚至已经取代了之前在局域网和广域网中常见的私有互联协议了。术语Internet被用来指将全球成千上万的计算机连接起来的TCP/IP互联网。

        第一个被广泛使用的TCP/IP实现出现在了1983年的4.2BSD上,一些TCP/IP实现是直接从BSD代码烟花而来的,其他的实现(包括Linux)则是从零开始编写的,但是他们在定义TCP/IP的操作时将BSD代码的操作当成了参考标准。

下图给出了一个简单的互联网。在这幅图中,机器tekapo是一种路由器,他是一台将一个自网络连接到另一个子网络并在他们之间传输数据的计算机。除了需要理解所使用的互联网协议之外,一台路由器还必须要理解他链接的各个子网所使用的(可能)不同的数据链路层协议。

使用一台路由器连接两个网络的互联网

 一台路由器拥有多个网络接口,每个接口都连接到一个子网上。更通用的术语“多宿主机”用来指拥有多个网络接口的任意主机---不必时一台路由器。(另一种描述路由器的方式是说他是将包从一个子网转发到另一个子网的一台多宿主机。)一个多宿主机的各个接口上的网络地址是不同的(即其连接的各个子网的地址是不同的)。

58.2 联网协议和层

一个联网协议是定义如何在一个网络上传输信息的一组规则。联网协议通常会被组织成一系列的层,其中每一层都构建于下层之上冰体同特性以供上层使用。

    TCP/IP协议套件是一个分层联网协议(见58-2)它包括因特网协议(IP)和位于其上层的各个协议层。(实现这些层的代码同城被称为协议栈)名字TCP/IP是从传输控制协议(TCP)是使用最为广泛的传输层协议这样一个事实而的出来的。

在图58-2中省略了其他一些TCP/IP协议,因为他们与本章的主题无关。地址解析协议(ARP)关注的是如何将因特网地址映射到硬件(如以太网)地址。因特网控制消息协议(ICMP)用来在网络中传输错误和控制信息。(ping和traceroute程序使用的就是ICMP协议,人们通常使用ping来检查一台特定的主机是否存活以及是否在TCP/IP网络中可见,使用traceroute来跟踪一个IP包在网络中的传输路径。)主机和路由器使用因特网组管理协议(IGMP)来支持数据报的多播

协议分层如此强大和灵活的其中一个原因是透明---每一个协议层都对上层隐藏下层的操作和复杂性,如一个使用TCP的应用程序只需使用标准的socket API并清楚自己正在使用一项可靠的字节流传输服务,而无需理解TCP的操作细节。(在61.9节中介绍socket选项时将会看到严格的讲,这一论断并不总是正确的,应用程序偶尔也需要清楚底层传输协议的操作细节。)应用程序也无需知IP和数据链路层的操作细节。从应用程序的角度来讲,他就像通过socket API直接与其他层进行通信了,如图58-3所示,其中虚线对应应用程序之间的虚拟通信路径以及两个主机上的TCP和IP实体。

封装

  封装是分层互联网协议中的一个重要原则。图58-4给出了TCP/IP协议层中的封装。封装中的关键概念是低层会将从高层向低层传递的信息(如应用程序数据、TCP段、IP数据报)当成不透明的数据来处理。换句话说,底层不会尝试对高层发送过来的信息进行解释。而只会将这字饿信息放到低层所使用的包中并在这个包向下传递到低层之前添加自身这一层的头信息。当数据从低层传递到高层时将会进行一个逆向的解包过程。

图58-2  TCP/IP套件中的协议

图58-3:通过TCP/IP协议进行的分层通信

   封装的概念还延伸到了数据链路层,其中IP数据报会被封装进网络帧中,但在图58-4中并没有显示出这些。封装可能还会延伸到应用层中,其中应用程序可能会按照自己的方式对数据进行打包

图58-4:TCP/IP协议层的封装

 58.3 数据链路层

      图58-2中的最低层是数据链路层,他是由设备驱动和底层物理媒介(如电话线、同轴电缆、或光纤)的硬件接口(网卡构成)。数据链路层关注的时在一个网络的物理连接上传输数据

  要传输数据,数据链路层需要将网络层传递过来的数据报凤凰金被称为帧的一个一个单元。除了需要被传输的数据之外,每个帧都会包含一个头,如头中坑包含了目标地址和帧的大小。数据链路层在物理连接上传输帧并处理来自接受者的确认。(不是所有数据链路层都使用确认。)这一层可能会进行错误检测、重传以及流量控制。一些数据链路层可能还会将大的网络包分成多个帧并在接受者端将这些帧进行重组。

从应用程序编程的角度来讲通常可以忽略数据链路层,因为所有的通信细节都是由驱动和硬件来处理的。 

对于有关IP的讨论来讲,数据链路层比较重要的一个特点是最大传输单元(MTU)

。数据链路层的MTU是该层所能传输的帧大小的上限,不同的数据链路层的MTU是不同的。

命令 netstat -i 会列出系统中所有的网络接口,包括 MTU.

58.4 网络层:IP

        位于数据链路层之上是网络层,他关注的是如何将包(数据)从源主机发送到目标主机。这一层执行了很多任务,包括以下几个。

  • 将数据分解成足够小的片段以便数据链路层进行传输(如有必要的话)
  • 在因特网上路由数据
  • 为传输层提供服务

 在TCP/IP协议套件中,网络层的主要协议是IP.在4.2BSD实现中出现的IP的版本是IP版本4(IPv4).在20世纪年代早期设计出了IP的一个修正版:IP版本6(IPv6).这两个版本之间最显著的差别在于IPv4使用32位地址来标识子网和主机,而IPv6则使用了128位的地址,从而能为主机提供更大的地址范围。虽然目前在因特网上IPv4任然是使用最广的IP版本,但在将来它会被IPv6所取代,IPv4和IPv6都支持高层的UDP和TCP传输协议

尽管从理论上来讲,32位的地址空间提供了数以亿计的IPv4网络地址,但是地址的结构和分配防止决定了实际可用的地址数量要少许多。IPv4地址空间的枯竭是创造IPv6主要原因

IPv4 和IPv6的存在引出了一个问题“IPv5”呢,事实上从来就没有IPv5这种东西。每个IP数据报头都包含了一个4位的版本号(即IPv4数据报的这个字段值总是数字4),而版本号5则被指派给了一个实验因特网零六歇息Internet Stream Protocol.在20世纪70年代最初构想的时候,这个面向连接的协议就被设计成支持音频和视频传输以及分布式仿真。由于IP数据报版本号5已经被指派过了,因此IPv4升级版 就使用了版本号 6。

  图58-2给出了一个裸socket(SOCK_RAW),他允许应用程序直接与IP层进行通信。这里不会对裸socket的使用进行描述,因为大多数应用程序会使用基于一种传输协议(TCP或UDP)之上的socket

IP传输数据报

      IP以数据报(包)的形式来传输数据。在两个主机之间发送的每一个数据都是在网络上独立传输的,他们经过的路径可能会不同。一个IP数据包含一个头,其大小范围是20个字节到60个字节。这个头中包含了目标主机的地址,这样就可以在网络上将这个数据报路由到目标地址了,此外还包含了包的源地址,这样就收主机就知道数据报的源头。

  一个IP实现可能会给他所支持的数据报的大小设定一个上限,所有IP实现都必须做到数据报的大小上限至少与规定的IP最小重组缓冲区大小一样大。在IPv4中这个限制是576字节;在IPv6中,这个限制是1500字节

IP是无连接和不可靠的 

  IP 是一种无连接协议,因为他并没有在相互连接的两个主机之间提供一个虚拟电路。IP也是一种不可靠的协议:他尽最大可能将数据报从发送者传送给接收者,但并不保证包到达的顺序与他们传输的顺序一样,也不保证是否重复,甚至都不保证包是否会到达接收者。IP也没有提供错误恢复(头信息错误的包会被静默的丢弃)。可靠性是通过使用一个可靠的传输协议(如TCP)或者应用程序本身来保证的。

  IPv4为IP头提供了一个校验和,这样能够检测出头部的错误,但并没有为保重所传输的数据提供任何错误检测机制。IPv6 并没有为IP头提供校验和,他一来高层协议来完成错误检测和可靠性。(UDP校验和在IPv4是可选的,但一般来讲都是启用的;UDP校验和在IPv6是强制的。TCP校验和在IPV4和IPv6中都是强制的)

  IP数据包的重复是可能发生的,因为一些数据链路层采用了一些技术来确保可靠性以及数据报可能会以隧道形式穿越一些采用了了重传机制的非TCP/IP网络。

IP可能会对数据报进行分段

  IPv4数据报的最大大小为65535字节。在默认情况下,IPv6允许一个数据报的最大大小为65575字节(40个字节用于存放头信息,65535自己用于存放数据),并且为更大的数据报提供了一个选项。

之前曾经提过大多数数据链路层回味数据帧的大小设定一个上限(MTU)。如常见的以太网架构中这个上限值是1500字节(比一个IP数据报的最大大小要小的多)。IP还定义了路径MTU的概念,他是源主机到目的主机之间路由上的所有数据链路层的最小MTU。(在实践中,以太网MTU通常是路径中最小的MTU.)

  当一个IP数据报的大小大于MTU时,IP数据报会分段(分解)成一个个大小适合在网络上的传输单元。这些分段在达到最终目的地之后会被重组成奥运是的数据报(每个IP分段本身就是包含了一个偏移量字段的IP数据报,该字段给出了一个该分段在原始数据报中的位置)

  IP分段的发生对于高层协议时透明的。并且一般来讲也并不希望发生这种事情。这里的问题在于由于IP并不进行重传并且只有在分段都达到目的地之后才能对数据报进行组转,因此如果其中一些分段丢失或包含传输错误的话就会导致整个数据报不可用。在一些情况下,这会导致极高的丢失率(适用于不进行重传的高层协议,如UDP)或降低传输速率(适用于进行重传的高层协议,如TCP).现代CP实现采用了一些算法(路径MTU发现)来确定主机之间的一条路径的MTU,并根据该值对传递给IP数据进行分解,这样IP就不会碰到需要传输大小超过MTU数据报的情况了。UDP并没有提供这种机制。

58.5 IP地址

  一个IP地址分为两个部分:一个是网络ID,它指定了主机所属的网络;另一个是主机ID,它标识了位于该网络中的主机。

IPv4 地址

  一个IPv4地址包含32位(图58-5)。当以人类可读的形式来表示时,这些地址通常采用点分十进制标记法,即将地址的四个字节写成一个十进制数字,中间以点号隔开,

                         图58-5:一个IPv4网络地址和对应的网络掩码

  当一个组织为其主机申请一组IPv4地址时,他会收到一个32位的网络地址以及yigeduiying-的32位的网络掩码。在二进制行驶中,这个掩码最左边的位由1构成,掩码中剩余部分的位用0填充,这些1表示地址中哪些部分包含了所分配到的网络ID,而这些0则表示地址中哪些部分可供组织用来为网络中的主机分配唯一的ID。掩码中网络ID部分的大小会在分配地址时确定。由于网络ID部分总是占据着掩码最左边的部分,因此可以使用下面的标记法拉指定分配的地址范围。

204.152.189.0/24

这里的/24表示的分配的网络ID 由最左边的24位构成,剩余的8位用于指定主机ID。或者在这种情况下也可以说网络掩码的点分十进制标记时255.255.255.0.

  拥有这个地址的组织可以见254个唯一的因特网地址分配给计算机---204.152.189.1到204.152.189.254。其中有两个地址是无法分配给计算机的,其中一个地址的主机ID的位都是0,它用来表示网络本身,另一个地址的主机ID位都是1----在本例中204.152.189.255-----他是子网广播地址。

  一些IPv4地址拥有特殊含义。特殊地址127.0.0.1一般被定义为回环地址,它通常会被分配给主机名localhost.(网络 127.0.0.0/8中的所有地址都可以被指定为IPv4回环地址,但通常会选择127.0.0.1.)发送到这个地址的数据报实际上不会到达网络,他会自动会还变成发送主机的输入。使用这个地址可以便捷的在同一主机上测试客户端和服务器程序。在C程序中定义了INADDR_LOOPBACK来表示这个程序。

  常量INADDR_ANY就是所谓的IPv4通配地址。通配IP地址对于将Internet domain socket 绑定到多宿主机上的应用程序来讲是比较有用的。如果位于一台多宿主机上的应用程序只将socket绑定到其中一个主机IP地址上,那么该socket就只能接收该IP地址上的UDP数据和TCP连接请求。但一般来讲都希望一台多宿主机上的应用程序能够接收指定任意一个主机IP地址的数据报和连接请求,而将socket绑定到统配IP地址上使之成为了可能。SUSv3并没有位INADDR_ANY规定一个特定的值,但是大多数实现将其定义成了0.0.0.0(全是0)。

  一般来讲,IPv4是划分子网的。划分子网将一个IPv4地址的主机ID部分分成两个部分:一个子网ID和一个主机ID(图58-6)。(如何划分主机ID完全由网络管理员来决定的。)子网划分原理在于一个组织通常不会将其所有主机接到单个网络。相反,组织可能会开启一组子网(一个“内部互联网络”),每个子网使用网络ID和子网ID组合起来标识。这种组合通常被称为扩展网络ID。在一个子网中,子网掩码所扮演的角色与之前描述的网络掩码的角色是一样的,并且可以使用类似的标记法来标识分配给一个特定子网的地址范围。

  假设分配到的网络ID是204.152.189.0/24,这样可以通过主机ID的8位中的4位划分成子网ID并将剩余的4位划分恒主机ID来对这个地址划分子网。在这种情况下,子网掩码将由28个前导1后面跟着4个0构成。ID为1的子网会被表示为204.152.189.16/28。

                                                                图58-6:IPv4 子网划分

  IPv6地址 

  IPv6地址的原理与IPv地址是类似的,他们之间关键的差别在于IPv6地址是由128位构成,其中地址的前面一些位是一个格式前缀,表示地址类型

  IPv6地址通常被书写成一系列用墨爱好隔开的16位的十六进制数字,如下所示。

  F000:0:0:0:0:0:A:1

  IPv6通常包含一个0序列,并且为了标记方便,可以使用两个分号(::)来表示这种序列。因此上面的地址可以被重写成:

F000:A:1

 在IPv6地址中智能出现一个双冒号标记,出现多次的话会造成混淆。

  IPv6地址也想IPv4那样提供了环回地址(127个0后面跟一个1即 ::1)和通配地址(所有都为0,可以书写为0::0)

  为允许IPv6应用程序与只支持IPv4的主机进行通信,IPv6提供了所谓的IPv4映射的IPv6地址,图58-7给出了这些地址格式

IPv4映射的IPv6地址形式

在书写IPv4地址映射的IPv6地址时,地址的IPv4地址部分(即最后4个字节)会被书写成IPv4的点分十进制标记。因此与204.152.189.116等价的IPv4映射的IPv6地址是::FFFF: 204.152.189.116。

58.6 传输层

  在TCP/IP套件中使用最广的两个传输层协议如下。

  • 用户数据报协议(UDP)是数据报socket所使用的协议。
  • 传输控制协议(TCP)是流socket所使用的协议。

在介绍这些协议之前首先要对两个协议都用到的端口号概念进行介绍。

58.6.1 端口号

  传输层协议的任务是向位于不同主机(或有时候位于同一主机)上的应用程序提供端到端的通信任务。为完成这个任务,传输层需要采用已汇总方法来区分一个主机上的应用程序。在TCP和UDP中,这种区分工作是通过一个16位的端口号来完成的。

众所周知的、注册的以及特权端口

  有些众所周知的端口号已经被永久地非陪给特定地应用程序了(也成为服务)。例如ssh(安全地shell)daemon使用众所周知地端口22,HTTP(Web和服务器之间通信时所使用地协议)使用众所周知地端口80.众所周知的端口号位于0~1023之间。它是由中央授权机构互联网号码分配局(IANA)来分配的。一个众所周知的端口号的分配是有一个被核准的网络规范(通常以RFC形式)来规定的。

IANA还记录着注册端口,将这些端口分配给应用程序开发人员的过程就不那个严格了(这也意味着一个实现无需保证这些端口是否真正应用于他们注册时申请的用途)。IANA注册的端口范围为1024~41951。(不是所有位于这个范围的端口都被注册了。)

  IANA众所周知的更新列表和注册端口分配情况可以在http://www.iana.org/assignments/
port-numbers上找到。

  在大多数TCP/IP实现(包括Linux)中,范围在0~1023间的端口号也是特权端口,这意味着只有特权(CAP_NET_BIND_SERVICE)进程可以绑定到这些端口上2,从而防止了普通用户实现恶意程序(如伪造ssh)来获取密码。(有些时候特权端口也被称为保留端口)

  尽管端口号相同的TCP和UDP端口是不同的实体,但同意额众所周知的端口号会同时分配给基于TCP和UDP的服务,即使该服务通常只提供了其中一种协议服务,这种惯例避免了端口号在两个协议中产生混淆的情况

临时端口

  如果一个程序没有选择一个特定的端口(即在socket术语中,他没有调用bind()将其socket绑定到一个特定的端口上),那么TCP和UDP会为该socket分配一个临时端口(即存活时间较短)。在这种情况下应用程序---通常是一个客户端---并不关心它所使用的端口号,但分配一个端口对于传输层协议标识通信端点来讲是有必要的。这种做法的另一个结果就是位于通信信道另一端的对等应用程序就知道如何与这个应用程序进行通信了。TCP和UDP在将socket绑定到端口0上时也会分配一个临时端口号

  IANA将位于49152到65535之间的端口称为动态或私有端口,这表示这些端口可供本地应用程序使用或作为临时端口分配。然后不同的实现可能会在不同的范围内分配临时端口。在linux上,这个范围是由包含在文件/proc/sys/net/ipv4/ip_local_port_range中的两个数字来定义的(可通过修改这两个值来修改范围)。

58.6.2 用户数据报协议(UDP)

  UDP仅仅在IP上添加了两个特性:端口号和一个进行检测传输数据错误的数据校验和。

  与IP一样,UDP也是无连接的。由于它并没有在IP之上增加可靠性,因此UDP是不可考的。如果一个基于UDP的应用程序需要确保可靠性,那么这些那个功能就必须要在应用程序中予以实现。如果剔除不可靠这个特点的话,有些时候可能倾向于使用UDP而不是TCP,具体原因可以在61.12节找到  。

  UDP和TCP使用校验和长度只有16位并且只是简单的“总结性”校验和,因此无法检测出特定的错误,其结果是无法提供较强的错误检测机制。繁忙的互联网服务器通常只能每隔几天看一下未检测出的传输错误的平均情况。需要更多确保数据完整性的应用程序可以使用安全Sockets层(Secure Sockets Layer,SSL),它不仅提供了安全的通信,而且还提供更加严格的错误检测过程。或者应用程序也可以实现自己的错误控制机制。

  选择一个UD[数据报大小以避免IP分段

    在58.4节中描述IP分段机制并指出通常应尽可能地避免IP分段。TCP提供了避免IP分段地机制,但是UDP并没有提供相应地机制,使用UDP时如果传输地数据报大小超过了本地数据连接地MTU,那么很容易会导致IP分段。

  基于UDP的应用程序通常不会知道源主机和目的主机之间的李静的MTU.一般来讲,基于UDP的应用程序会采用保守的方法来避免IP分段,即确保传输的IP数据报的大小小于IPv4的组装缓冲区的最小值576字节。(这个值很可能是要小于路径MTU的。)在这576字节中有8个字节是用于放UDP头的,另外最少需要使用20个字节来存放IP头,剩下的548字节用于存放UDP数据本身。在实践中,很多基于UDP的应用程序会选择使用一个更小的512字节来存放数据报。

58.6.3 传输控制协议(TCP)

  TCP在两个端点(即应用程序)之间提供了可靠的,面向链接的、双字节流通信铣刀,如图58-8所示,为提供这些特性TCP必须要执行本节中描述的任务。

58-8:已连接的TCP socket

 

   这里使用术语TCP端点来表示连接一端的内核所维护的信息。(通常会进一步对这个属于进行缩写,如仅书写“一个TCP”来表示“一个TCP端点”或“客户端TCP”来表示“客户端应用程序维护的TCP端点。”)这部分信息包括链接这一端的发送和接收缓冲区以及维护的用来同步两个已连接的端点的操作的状态信息。

连接建立

  在开始通信之前,TCP需要在两个端点之间建立一个通信信道。在连接建立期间,发送和接受者需要交换选项来协商通信的参数。

将数据打包成段

  数据会被分解成段,每一个段都包含一个校验和,从而能够检测出端到端的传输错误。每一个段使用单个IP数据报来传输。

确认、重传以及超时

  当一个TCP无措的到达目的地时,接受TCP会向发送者发送一个确认,通知他有数据发送成功了。如果一个段在到达时是存在错误的,那么这个段就会被丢弃,确认信息也不会被发送。为处理段永远不到达或者被丢弃的情况,发送者在发送每一个段时会定时开启一个定时器。如果在定时器超时之前没有收到确认,那么就会重传这个段。

  由于所使用的网络以及当前的流量负载会影响传输一个段和接收其确认所需的时间,因此TCP采用了一个算法来动态的调整重传超时时间

  接收TC可能不会立即发送确认。而是会等待几毫秒来观察一下是否可以将确认塞进接受者返回给发送者的响应中。(每个TCP段都包含一个确认字段,这样就能够将确认字段塞进TCP段中了。)这项被称为延时ACK技术的目的是能少发送一个TCP段,从而降低网络中包的数量以及降低发送和接受主机的负载。

排序

   在TCP连接上传输的每一个字节都会分配到一个逻辑序号。这个数字指出了该字节在这个连接的数据流中所处的位置。(这个连接中的两个流各自都有自己的序号计数系统。)当传输一个TCP分段时会在其中一个字段中包含这个段的第一个字节的序号。

  在每一个段中加上一个序号有几个作用。

  • 这个序号使得TCP分段能够以正确的顺序在目的地进行组装,然后以字节流形式传递给应用层。(在任意一个时刻,在发送者和接受者之间可能存在多个正在传输的TCP分段,这些分段的到达可能与被发送的顺序不同。)
  • 由接收者返回给发送者的确认消息可以使序号来标识出收到了哪个TCP分段。
  • 接收者可以使用序号来移除重复的分段。发生重复的原因可能是因为IP数据段重复,也可能是因为TCP自己重传算法会在一个段确认丢失或者没有按时收到时重传一个成功递出去的段。

  一个流的初始序号(ISN)不是从0开始的,相反,他是通过一个算法来生成的,该算法会递增分配给后续TCP连接的ISN(为防止出现前一个连接中的分段与这个连接中的分段混淆的情况)。这个算法也使得猜测ISN变得困难起来。序号是一个32位的值,当达到最大取值时会回到0。

流量控制

  流量控制防止一个快速的发送者将一个慢速的接收者压垮。要实现流量控制,接收TCP就必须要为进入的数据维护一个缓冲区。(每个TCP在连接建立阶段会通告其缓冲区的大小。)当从发送TCP端接收到数据时会将数据累计在这个缓冲区中,当应用程序读取数据时会从缓冲区中删除数据。在每个确认中,接受者会通知发送者其进入数据缓冲区的可用空间(即发送者可以发送多少字节)。TCP流量控制算法采用了所谓的滑动窗口算法,他允许包含总共N字节(提供窗口的大小)的未确认段同时在发送者和接收者之间传输。如果接收TCP的进入数据缓冲区完全被充满了,那么窗口就会关闭,发送TCP 就会停止传输数据。

拥塞控制:慢启动和拥塞避免算法

  TCP的拥塞控制算法被设计用来防止快速的发送者压垮整个网络。如果一个发送TCP发送包的速度要快于一个中间路由器转发的速度,那么该路由器就会开始丢包。这样就会导致较高的丢包率,其结果是如果TCP保持以相同的速度发送这些被丢弃的分段的话就会极大地降低性能。TCP的拥塞算法在下列两个场景中还是比较重要的。

  • 在连接建立之后:此时(或当传输在一个我已经空闲了一段时间的连接上恢复时),发送者可以立即向网络中诸如尽可能多的分段,只有接受者公告的窗口大小允许即可。(事实上,这就是早期的TCP实现的做法 。)这里的问题在于如果网络无法处理这种分段洪泛,那么发送者可能会存在立即压垮整个网络的风险。
  • 当拥塞被检测到时:如果发送TCP检测到发生了拥塞,那么他就必须要降低其传输速率。TCP是g根据分段丢失来检测是否发生了拥塞,因为传输错误率是非常低的,即如果一个包丢失了,那么就认为是发生了拥塞。

  TCP的拥塞控制策略组合采用了两种算法:慢启动和拥塞避免。

  慢启动算法会是发送TCP在一开始的时候以低速传输分段,但同时允许它以指数级的速度提高其速率。只要这些分段都得到接收TCP的确认。慢启动能够防止一个快速的TCP发送者压垮整个网络。但是如果不加限制的话,慢启动在传输速率上的指数级增长意味着发送者在短时间内就会压垮真个网络。TCP的拥塞避免算法用来防止这种情况的发生,它为速率的增长安排了一个管理实体。

  有了拥塞避免之后,在连接刚建立时,发送TCP会使用一个较小的拥塞窗口,它会限制所能传输的未确认的数据数量。当发送者从对等TCP处接收到确认时,拥塞窗口在一开始时会呈现指数级增长。但一旦拥塞窗口增长到一个被认为时接近网络传输容量的阈值时,其增长的速度就会变成线性,而不是指数级的。(对网络容量的估算时根据检测到拥塞时的传输速率来计算得出的或者在一开始建立连接时设定为一个固定值。)在任何时刻,发送TCP传输的数据数量还会收到接收TCP的通告和本地的TCP发送缓冲期的大小的限制。

  慢启动和拥塞避免算法组合起来使得发送者可以快速的将传输速度提升至网络的可用容量,并且不会超出该容量。这些算法的作用是允许数据传输快速的到达一个平衡状态,及发送者传输包的速率与它从接收者处接收确认的速率一致

58.8 总结

  TCP/IP  是一个分层的联网协议套件。在TCP/IP协议栈的最底层是IP网络层协议。IP以数据报的形式传输数据。IP是无连接的,表示在源主机和目的主机之间传输的数据报可能经过网络中的不同路径。IP是不可靠的,因为他不保证数据报会按顺序以及不重复到达,甚至还不保证数据报一定会到达。如果压球可靠性的话,就必须要通过使用一个可靠的高层协议(如TCP)或在应用程序中完成。

  IP最初的版本时IPv4.在20世纪90年代早期,IP的一个新版本IPv6被设计出来了,IPv4和IPv6之间最显著的差别在于IPv4使用了32位来表示一个主机地址,而IPv6则使用了128位,从而允许全球范围的因特网中介入更多的主机。目前,IPv4任然是使用最为广泛的IP,尽管在将来可能会被IPv6替代。

  在IP之上存在多种传输层协议,其中使用最多的就是UDP和TCP.UDP是一个不可靠的数据报协议。TCP是一个可靠的,面向连接的字节流协议。TCP处理了连接建立和终止的所有细节,TCP还将数据打包成分段以供IP传输并为这些分段提供了序号计数,这样接收者就能对这些分段进行确认并以正确的顺序组装这些分段。此外,TCP还提供了流量控制来防止一个快速的发送者来压垮一个慢速的接受者和拥塞控制来防止一个快速的发送者压垮整个网络。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值