热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

计算机网络自顶向下方法第3章-传输层(TransportLayer).2

3.5面向连接的运输:TCP3.5.1TCP连接TCP是因特网运输层的面向连接的可靠的运输协议。TCP连接提供全双工服务(full-duplexservice).

3.5 面向连接的运输: TCP

  3.5.1 TCP连接

  • TCP是因特网运输层的面向连接的可靠的运输协议。
  • TCP连接提供全双工服务(full-duplex service).
  • TCP连接是点对点的连接.

  1).最大报文段长度(Maximum Segment Size,MSS):该术语很容易被混淆,它其实指的是报文段里应用数据的最大长度,而不是包括TCP首部的TCP报文段的最大长度。

  2).最大传输单元(Maximun Transmission Unit,MTU):指的是最大链路层帧长度,即应用数据+TCP首部+IP首部.

  3.5.2 TCP报文段结构

  

  1.序号和确认号。

  

  在TCP协议中,序号是对应用层所要发送的数据的字节流的编号,而不是对报文段的编号。举例来说,进程A想要想进程B发送50000字节的数据,而其MSS为1000字节。那么,在TCP协议中,第一个报文段的序号是0,第二个报文段的序号是1000,第三个报文段的序号是2000......以此类推。序号表示的是:当前的报文段中应用层数据的首个字节在整个字节流中的位置。
  

  TCP连接是全双工的,当主机A向主机B发送数据的同时,也有可能受到来自主机B的数据。举例来说,A收到了B发送的0~535的报文,同时它打算发送一个报文给B,那它的发送的这条报文的确认号将为536,表示它希望下一个接收到的报文的第一个序号是536 (当然,这条报文的初始序号是主机A自己随机选择的,比如0)

  2.Telnet : 序号与确认号的一个学习案例。

  假设客户端A的起始序号是42,服务器B的起始序号是79。在客户端中中输入一个字符‘c’,那么从A发出的报文应该是一个序号=42,确认号=79,data='c' 的TCP报文(前面说过,确认号指的是期待收到的下一个字节序号。在双方还没开始互发数据之前,客户端A等待的是79,而服务端B等待的是42)

  

  3.5.3 往返时间的估计与超时

  1.估计往返时间

  报文段的“样本RTT”(SampleRTT)就是指某报文段被发出到该报文段的确认被收到的时间间隔。TCP维护一个SampleRTT的均值EstimatedRTT,每次收到一个新的SampleRTT,就对这个EstimatedRTT进行更新,“RTT偏差”(DevRTT)用于估算SampleRTT偏离EstimateRTT的程度

  2.设置和管理重传超时间隔

  3.5.4 可靠数据传输

  由于TCP是在IP不可靠的、尽力而为的服务上建立的一种可靠数据传输协议,即确保接收端从其接受缓存中读取到的数据是无损坏、无间隔、非冗余和按序的。但TCP的报文是被IP数据报携带着在网络中传输的,有可能会出现比特错误、丢包。失序到达等问题,TCP如何保证数据的可靠性呢?

  1. 在TCP的接收端,维护一个nextrcvseqnum变量,保存接收端下一个要接收的最小有序的报文段的序号。

  ①当接受到的报文的是正确的并且序号为nextrcvseqnum时,更新接收端的nextrcvseqnum,使nextrcvseqnum = nextrcvseqnum+sizeof(接收到的数据),回送确认号为nextrcvseqnum的ACK

  ②当接收到的报文是正确的,当序号>nextrcvseqnum时,先将这个报文缓存起来,然后继续回复确认号为nextrcvseqnum的ACK告诉发送方自己现在最想要的是序号为nextrcvseqnum的报文。 

  ③当接收到的报文是正确的,但序号

  ④当接受到的报文是错误的,则不管序号是什么,接收端丢弃这个报文,并回复确认号为nextrcvseqnum的ACK

  2. 在TCP的发送端,需要为最早发送、未被确认的报文段维护一个baseSend变量来保存其序号和一个定时器来记录其等待时间是否超时。

  ①当发送端接收到一个确认序号num>baseSend的ACK报文,那么,由于TCP采用的是累积确认机制,所以发送方知道序号<=num的报文都已经正确到达接收端了。所以发送端更新最早发送、未被确认的序号baseSend=num。如果当前还有未被确认的报文段,TCP还要重新启动定时器。

  ②当发送端接收到一个确认序号=baseSend的ACK报文(当确认序号=baseSend时,说明接收方是为baseSend的上一个报文回送的ACK)时,它的定时器会继续运行,并统计接收到的冗余ACK的数量。当接收到对相同数据的3个冗余ACK时,发送方不等定时器的超时时间,直接快速重传序号为baseSend的ACK报文(可以减少等待超时的时间,提升性能),并重新启动定时器。

  ③当发送端接收到一个序号

  ④当发送端的定时器过期时,还没有收到序号>baseSend的ACK,则发送端重传序号为baseSend的报文,并将定时器的值增加一倍。

  TCP的可靠数据传输协议是在GBN的基础上,进行了改造。首先,GBN的接收端不会存储任何失序报文,所以GBN遇到超时事件会直接重传所有未被确认的报文,而TCP中只需重传最小未被确认的报文即可;其次,在TCP中加入了冗余ACK机制,可以实现快速重传,不必每次都等待漫长的超时事件的发生。二者大大提高了传输协议的整体性能。  

  3.5.5 流量控制

  TCP为它的应用程序提供了流量控制服务(flow-control service)以消除发送方使接收方缓存溢出的可能性(TCP的发送端也有可能因为IP网络的拥塞而被遏制,这种形式的控制成为拥塞控制(congestion control))

  3.5.6 TCP 连接管理

  1. TCP连接的建立:客户端发起

  TCP连接的建立也成为三次握手协议,通过以下三个步骤:

  (1)首先,客户端想服务端发送一个特殊的“SYN报文”,这个报文不包含应用数据,但其首部的一个标志位SYN被置为1。另外,客户端会随机选择一个初始序号client_isn,并将此编号放入报文的序号字段中;

  (2)一旦服务器接收到SYN报文,服务器为TCP连接分配TCP缓存和变量,并向客户TCP发送允许连接的SYNACK报文。在SYNACK报文中,SYN比特被置为1,首部的确认字段被置为client_isn+1,最后,服务器选择自己的随机起始序号server_isn,放入序号段中。

  (3)在收到SYNACK后,客户端也要为自己的TCP连接分配TCP缓存和变量,并且向服务器发送一个报文,这个报文是对服务器的允许连接的一个确认。这个报文段的确认字段为server_isn+1;而由于此时连接已经建立,所以SYN比特被置为0。并且,在这个报文段里,可以携带应用层数据。
   

  

  2. TCP连接的拆除,四次挥手

  参与TCP连接的两个进程中的任意一个都能终止该连接。假设客户端打算终止连接:

  (1)客户TCP向服务器进程发送一个特殊的报文,这个报文首部的FIN标志位被置为1;

  (2)当服务器接收到这个报文时,他发送一个回送ACK报文

  (3)服务器发送它的终止报文,其FIN标志位被置为1

  (4)最后,该客户对服务器的终止报文进行确认。此时,这两台主机上用于该连接的所有资源都被释放了。
  

3.6 拥塞控制原理

  3.6.1 拥塞原因与代价

  •  网络传输中某些数据的丢失是因为网络的拥塞而导致的路由器的缓冲区的溢出而造成的。
  •  当分组到达的速率接近链路容量的时候,会产生很大的队列等待延迟。
  •  发送方为了对路由器缓冲区溢出所产生的分组丢失做出补偿,就必须执行数据的重发操作。
  •  当发生超长时间延迟时,发送方所进行的重传操作可能会导致路由器浪费其带宽去传送一些不必要的分组副本。
  •  当一个分组在传送路径中丢失,那么前面所有发送过该分组的、一直到丢失该分组的路由器所做的传输工作就都浪费了。

  3.6.2 拥塞控制方法

  • 端到端的拥塞控制
  • 网络层发生作用的拥塞控制

3.7 TCP 拥塞控制

  TCP 的拥塞控制主要来避免两种现象,包丢失和超时重传。一旦出现了这些现象就说明,发送速度太快了,要慢一点。TCP的拥塞控制主要原理依赖于一个拥塞窗口(cwnd)来控制  

  1.慢启动

  最初的TCP在连接建立成功后会向网络中发送大量的数据包,这样很容易导致网络中路由器缓存空间耗尽,从而发生拥塞。因此新建立的连接不能够一开始就大量发送数据包,而只能根据网络情况逐步增加每次发送的数据量,以避免上述现象的发生。具体来说,当新建连接时,cwnd初始化为1个最大报文段(MSS)大小,发送端开始按照拥塞窗口大小发送数据,每当有一个报文段被确认,cwnd就增加1个MSS大小。这样cwnd的值就随着网络往返时间(Round Trip Time,RTT)呈指数级增长,事实上,慢启动的速度一点也不慢,只是它的起点比较低一点而已。

  一条 TCP 连接开始,cwnd 设置为一个报文段,一次只能发送一个;当收到这一个确认的时候,cwnd 加一,于是一次能够发送两个;当这两个的确认到来的时候,每个确认 cwnd 加一,两个确认 cwnd 加二,于是一次能够发送四个;当这四个的确认到来的时候,每个确认 cwnd 加一,四个确认 cwnd 加四,于是一次能够发送八个。可以看出这是指数性的增长。

  2.拥塞避免

  从慢启动可以看到,cwnd可以很快的增长上来,从而最大程度利用网络带宽资源,但是cwnd不能一直这样无限增长下去,一定需要某个限制。TCP使用了一个叫慢启动门限(ssthresh)的变量,当cwnd超过该值后,慢启动过程结束,进入拥塞避免阶段。对于大多数TCP实现来说,ssthresh的值是65536(同样以字节计算)。拥塞避免的主要思想是加法增大,也就是cwnd的值不再指数级往上升,开始加法增加。此时当窗口中所有的报文段都被确认时,cwnd的大小加1,cwnd的值就随着RTT开始线性增加,这样就可以避免增长过快导致网络拥塞,慢慢的增加调整到网络的最佳值。

  涨到什么时候是个头呢?有一个值 ssthresh 为 65535 个字节,当超过这个值的时候,就要小心一点了,不能倒这么快了,可能快满了,再慢下来。 每收到一个确认后,cwnd 增加 1/cwnd,我们接着上面的过程来,一次发送八个,当八个确认到来的时候,每个确认增加 1/8,八个确认一共 cwnd 增加 1,于是一次能够发送九个,变成了线性增长。

  3.快速重传与快速恢复

  拥塞的一种表现形式是丢包,需要超时重传,这个时候,将 sshresh 设为 cwnd/2,将 cwnd 设为 1,重新开始慢启动。这真是一旦超时重传,马上回到解放前。但是这种方式太激进了,将一个高速的传输速度一下子停了下来,会造成网络卡顿。快速重传算法:当接收端发现丢了一个中间包的时候,发送三次前一个包的 ACK,于是发送端就会快速的重传,不必等待超时再重传。TCP 认为这种情况不严重,因为大部分没丢,只丢了一小部分,cwnd 减半为 cwnd/2,然后 sshthresh = cwnd,当三个包返回的时候,cwnd = sshthresh + 3,也就是没有一夜回到解放前,而是还在比较高的值,呈线性增长。

参考

  https://blog.csdn.net/qq_36464448/article/details/80409476 

  https://blog.csdn.net/peijian1998/article/details/25684937 

  https://blog.csdn.net/itmacar/article/details/12278769


推荐阅读
  • 在《Linux高性能服务器编程》一书中,第3.2节深入探讨了TCP报头的结构与功能。TCP报头是每个TCP数据段中不可或缺的部分,它不仅包含了源端口和目的端口的信息,还负责管理TCP连接的状态和控制。本节内容详尽地解析了TCP报头的各项字段及其作用,为读者提供了深入理解TCP协议的基础。 ... [详细]
  • Java Socket 关键参数详解与优化建议
    Java Socket 的 API 虽然被广泛使用,但其关键参数的用途却鲜为人知。本文详细解析了 Java Socket 中的重要参数,如 backlog 参数,它用于控制服务器等待连接请求的队列长度。此外,还探讨了其他参数如 SO_TIMEOUT、SO_REUSEADDR 等的配置方法及其对性能的影响,并提供了优化建议,帮助开发者提升网络通信的稳定性和效率。 ... [详细]
  • SecureCRT是一款功能强大的终端仿真软件,支持SSH1和SSH2协议,适用于在Windows环境下高效连接和管理Linux服务器。该工具不仅提供了稳定的连接性能,还具备丰富的配置选项,能够满足不同用户的需求。通过SecureCRT,用户可以轻松实现对远程Linux系统的安全访问和操作。 ... [详细]
  • 小王详解:内部网络中最易理解的NAT原理剖析,挑战你的认知极限
    小王详解:内部网络中最易理解的NAT原理剖析,挑战你的认知极限 ... [详细]
  • 如何在Linux服务器上配置MySQL和Tomcat的开机自动启动
    在Linux服务器上部署Web项目时,通常需要确保MySQL和Tomcat服务能够随系统启动而自动运行。本文将详细介绍如何在Linux环境中配置MySQL和Tomcat的开机自启动,以确保服务的稳定性和可靠性。通过合理的配置,可以有效避免因服务未启动而导致的项目故障。 ... [详细]
  • 本文介绍了如何使用Python的Paramiko库批量更新多台服务器的登录密码。通过示例代码展示了具体实现方法,确保了操作的高效性和安全性。Paramiko库提供了强大的SSH2协议支持,使得远程服务器管理变得更加便捷。此外,文章还详细说明了代码的各个部分,帮助读者更好地理解和应用这一技术。 ... [详细]
  • 本文介绍了如何利用Shell脚本高效地部署MHA(MySQL High Availability)高可用集群。通过详细的脚本编写和配置示例,展示了自动化部署过程中的关键步骤和注意事项。该方法不仅简化了集群的部署流程,还提高了系统的稳定性和可用性。 ... [详细]
  • Web开发框架概览:Java与JavaScript技术及框架综述
    Web开发涉及服务器端和客户端的协同工作。在服务器端,Java是一种优秀的编程语言,适用于构建各种功能模块,如通过Servlet实现特定服务。客户端则主要依赖HTML进行内容展示,同时借助JavaScript增强交互性和动态效果。此外,现代Web开发还广泛使用各种框架和库,如Spring Boot、React和Vue.js,以提高开发效率和应用性能。 ... [详细]
  • 利用 Python Socket 实现 ICMP 协议下的网络通信
    在计算机网络课程的2.1实验中,学生需要通过Python Socket编程实现一种基于ICMP协议的网络通信功能。与操作系统自带的Ping命令类似,该实验要求学生开发一个简化的、非标准的ICMP通信程序,以加深对ICMP协议及其在网络通信中的应用的理解。通过这一实验,学生将掌握如何使用Python Socket库来构建和解析ICMP数据包,并实现基本的网络探测功能。 ... [详细]
  • 对于希望在未越狱的iOS设备上修改Hosts文件的苹果用户来说,了解文件的具体位置和操作步骤至关重要。本文将详细介绍如何通过安装最新版本的iTunes来实现这一目标,并提供实用的操作指南,帮助用户轻松完成Hosts文件的编辑。 ... [详细]
  • 本文详细介绍了一种利用 ESP8266 01S 模块构建 Web 服务器的成功实践方案。通过具体的代码示例和详细的步骤说明,帮助读者快速掌握该模块的使用方法。在疫情期间,作者重新审视并研究了这一未被充分利用的模块,最终成功实现了 Web 服务器的功能。本文不仅提供了完整的代码实现,还涵盖了调试过程中遇到的常见问题及其解决方法,为初学者提供了宝贵的参考。 ... [详细]
  • 本文详细介绍了在Linux系统上编译安装MySQL 5.5源码的步骤。首先,通过Yum安装必要的依赖软件包,如GCC、GCC-C++等,确保编译环境的完备。接着,下载并解压MySQL 5.5的源码包,配置编译选项,进行编译和安装。最后,完成安装后,进行基本的配置和启动测试,确保MySQL服务正常运行。 ... [详细]
  • 本指南详细介绍了在Linux环境中高效连接MySQL数据库的方法。用户可以通过安装并使用`mysql`客户端工具来实现本地连接,具体命令为:`mysql -u 用户名 -p 密码 -h 主机`。例如,使用管理员账户连接本地MySQL服务器的命令为:`mysql -u root -p pass`。此外,还提供了多种配置优化建议,以确保连接过程更加稳定和高效。 ... [详细]
  • 在使用 SQL Server 时,连接故障是用户最常见的问题之一。通常,连接 SQL Server 的方法有两种:一种是通过 SQL Server 自带的客户端工具,例如 SQL Server Management Studio;另一种是通过第三方应用程序或开发工具进行连接。本文将详细分析导致连接故障的常见原因,并提供相应的解决策略,帮助用户有效排除连接问题。 ... [详细]
  • 本文探讨了 Kafka 集群的高效部署与优化策略。首先介绍了 Kafka 的下载与安装步骤,包括从官方网站获取最新版本的压缩包并进行解压。随后详细讨论了集群配置的最佳实践,涵盖节点选择、网络优化和性能调优等方面,旨在提升系统的稳定性和处理能力。此外,还提供了常见的故障排查方法和监控方案,帮助运维人员更好地管理和维护 Kafka 集群。 ... [详细]
author-avatar
唯忻小十__
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有