1.认识TCP

  tcp协议是传输层协议,它的最主要的3个特点是面向连接、可靠保证、基于字节流。当应用层把数据给tcp层时,注意如果数据大于MSS是要在tcp层进行分段的。tcp协议为了保证不丢包会给每个包一个序号,接受方成功收到数据包后回回复一个确认,这个过程是在小于传输延迟RTT的时间内的。如果发送方在RTT时间内没有收到确认就会重传已丢失的数据包。说到要在tcp层进行分段我就想到老师经常提到以太网数据包的长度要小于或等于1518和大于或等于46字节,但我却还不知道是什么原因。还有一个问题,在tcp层会对数据进行分段,它和分片的区别是什么。

问题一:为什么以太网数据帧大小在64字节和1518字节之间?

  可以想象A给B发数据,发送数据这个过程本身是需要时间的,现在已经有部分数据在传输链路上了,B这时也准备发送数据。那么B这时就会检测到冲突并将冲突信号返回给A,如果冲突信号返回给A时,A的数据还没发送完那么A就知道有冲突,这样数据就会选择合适的时间重发。如果冲突信号到达A时A已经把数据发送完了,那么A就不会重传数据了。所以在一个往返时间内,数据不能发送完,因此以太网数据帧最小为64字节。如果数据帧太大,一方面其他主机需要长时间等待,一方面可能造成接受方缓冲区溢出,因此数据帧一定要小于一个值,至于为什么是1518那就是数学和其他多方面考虑得出的结果了。

问题二:Tcp层的分片和IP层的分片有什么区别?

  我刚开始在TCP百度百科查看到“然后TCP把数据流分区成适当长度的报文段(通常受该计算机连接的网络的数据链路层的最大传输单元([1]  MTU)的限制)”这样一句话。我觉得很奇怪,tcp层的分段难道还和数据链路层的MTU有关系,既然已经有了IP分片,tcp层分段有什么意义呢?查阅资料后发现tcp分段是根据最大传输单元MSS来进行的,MSS是建立tcp连接后,双方协商的进行通信时所能承受的最大数据长度。当使用IP分片时有一个最大的缺点那就是一旦丢失一个分片,就会重新传输整个数据报。采用tcp分段的话它的数据长度是要小于MSS的,而MSS是小于MTU的,这样的话就将重传机制就交给tcp负责了。

2.TCP首部的作用

  下面是一个tcp首部的图,源端口与目的端口的作用不言而喻。序列号对应着tcp报文段里的每一个字节,它的值是报文段将发送的第一个字节所对应的序列号与2^32取余的结果。比如现在序列号为100,要发送100个字节,那么下次发送时序列号将为200。ACK指的是对方下一个报文段的序列号,如果ACK=n,那么可以表明n-1为止的所有数据都已正确的收到。从seq和ack可以看出这就是滑动窗口的具体实现,发送方的seq对应着滑动窗口的始端,发送方收到的ack对应着滑动窗口可以前移的字节数。在seq和ack的基础上,再加上超时重传机制就可以实现数据重复、数据丢失、数据乱序的处理,总之就是只有收到接收方的ack后发送方才可以发送数据。数据偏移只占4位,这个字段的意思其实就是tcp首部(可选首部和固定首部)的真实长度,保留为6位供今后使用。窗口指的是自己此时滑动窗口的大小,它告诉接收方你可以发送的字节数。校验和占2字节,校验的范围包括首部和数据这两部分,首部中要注意会加上伪首部。紧急指针仅在URG=1时才有意义,它指出了本报文段中的紧急数据的字节数,紧急数据之后的就是普通数据了,有一点要注意,即使现在窗口大小为0仍然可以发送紧急数据。

可选项中长度可变,最多为40个字节。上面提到的MSS最大报文段长度就是可选项中的,还有一些可选项包括窗口扩大选项、时间戳等。扩大窗口顾名思义就是增加窗口值,它占3个字节。原来窗口最大为64kb,对于某些应用已经无法满足需求了,而窗口扩大可让窗口值最大为2^30-1,也就是说在这3个字节中拿出了14位来表示窗口值。时间戳占10个字节,它包括时间戳值和时间戳会送回答字段。时间戳主要用来得到往返时间RTT和防止序号绕回。当序号使用到最大值而归0时可能会出现2个数据包拥有相同的序列号,这时就需要使用时间戳来判断这2个包哪个是先来的哪个是后来的。最后还剩下6个控制位我画了一张图来说明。

3.TCP连接建立与释放

  昨天参加笔试这个地方就没有答的很深入,只说了一个大概。所以今天得认真的学习下tcp,确实网络挺重要的。tcp连接断开主要是三次握手和四次握手,下面是我总结的一个表格。

建立连接 参数字段 状态
客户端请求服务器 SYN=1,seq=x,SYN报文段不能携带数据。 客户端进入SYN-SENT状态
服务器回复客户端 SYN=1,ACK=1,seq=y,确认号ack=x+1,仍然不能携带数据。 服务器进入SYN-RCVD状态
客户端回应服务器 ACK=1,seq=y+1,确认号ack=x+1。 服务器收到后客户端和服务器同时进入ESTABLISHED状态
释放连接 参数字段 状态
A向B发送连接释放报文 FIN=1,seq=u。 A进入FIN-WAIT-1状态,等待B的确认。
B回复确认 ACK=1,seq=v,ack=u+1。 B进入CLOSE-WAIT,这时B的tcp进程通知高层进程去释放连接,B进入半关闭状态,这个时候B不会接受数据但是可能发送数据。
A收到确认后  不会发送数据包  A进入FIN-WAIT-2状态,等待B发出连接释放数据报
 B发送连接释放数据包 FIN=1,ACK=1,seq=w,ack=u+1。   B进入LAST-ACk最后确认状态,等待A的确认。
A收到B的连接释放包后,返回确认。 ACK=1,seq=u+1,ack=w+1。  发送数据后,A进入到TIME-WAIT状态,现在TCP连接还没有释放掉,必须经过时间等待计时器设置的时间2MSL(时间等待状态)后A才能进入到CLOSED状态。B收到数据报后也会进入CLOSED状态,这样A和B就断开连接了。

问题三:为什么A在发送确认数据后必须等待2MSL时间呢?

  有2个理由,第一是最后一个A发送确认报文后,这个报文有可能丢失。如果B收不到A已发送确认报文那么B会重传FIN+ACK报文段,A经过2MSL的好处就体现在这了,在2MSL内A还可以收到B重传的数据包。A收到重传的数据后会再重传一次确认,重新启动2MSL计时器。第二点是就是可以产生一个延迟,在2MSL时间内可保证本连接持续时间内所产生的报文段从网络中消失,这样就可以使下一个新的连接中不会出现上一次的数据报文段。

4.TCP的可靠性与拥塞控制

  TCP的可靠性主要体现在滑动窗口机制和超时重传。tcp的滑动窗口是以字节为单位的,当发送方发送数据时,接收方收到数据后会对收到的数据进行确认,发送方只有收到接收方的确认后才会将滑动窗口向前移动。滑动窗口机制可以保证数据被可靠的接受。每当发送方发送一个数据段时,就会启动一个重传定时器,如果在重传超时前收到确认则会停止定时器,否则就会重传该数据段。另外TCP会保持首部和数据的校验和,当校验和有差错时,TCP将会丢弃这个报文段且不会确认收到此数据包,这样做还有一个目的就是希望发送端超时重传。TCP还能提供流量控制,发送方或接受方会相互通信传递自己的缓冲区大小,这样发送方只会给接收方发送接收方可以容纳的数据,这可以防止缓冲区溢出。

  拥塞控制的目的就是为了防止过多的数据注入到网络中,这样可使网络中的路由器或链路不致过度负荷,而且实现拥塞控制的前提是网络可以承受现有的负荷。拥塞控制常常和流量控制搞混淆,我觉得可以从相同点与不同点去看这个问题。本来拥塞控制算法说到底就是告诉发送端你要减慢发送数据了,网络现在有麻烦了你必须降低流量的出口,这点和流量控制是很相似的。但是拥塞控制是一个全局的过程,而流量控制往往是点对点通信量的控制,是端到端的关系。流量控制所要做得事情就是需要发送方减慢发送速度时抑制发送方的发送速度让接收方来得及接受。进行拥塞控制主要是根据一些指标来判断当前网络的状况,比如超时重传的分组数或丢弃的数据包百分比等等。网络系统进行控制肯定是很复杂的,我这里主要是总结课本上的4个算法,了解了网络拥塞控制的基本原理。其中慢开始算法和拥塞控制算法一起结合使用。慢开始、快重传和快恢复结合使用,但是慢开始仅仅在tcp建立连接时和网络出现超时时才使用。

序号 过程描述 发送方 接收方 状态
1 网络正常情况 维持拥塞窗口的状态变量,大小取决于网络的拥塞程度。 做好接受数据的准备, 发送方会让发送窗口大小等于拥塞窗口大小,这个窗口大小是动态变化的且原则是只要没出现网络拥塞,拥塞窗口就会增大一些。
2 发送方开始发送数据 探测拥塞窗口并逐渐由小增大拥塞窗口的数值,当开始发送报文段时会将发送窗口增加为MSS的数值。 接受方对结果进行回复确认 接受方每收到一个新的报文段的确认后就会增加最多一个MSS大小的窗口值。这个过程为慢算法,就是每完成一个传输过程,拥塞窗口就会增加。
3 是否达到慢开始门限 为了防止拥塞窗口过度增加会设置一个慢开始门限ssthresh变量。 接受方接受数据 如果拥塞窗口小于ssthresh继续执行慢开始算法,如果是大于则停止使用慢开始算法而改用拥塞避免算法。如果是等于的话两种算法都可以执行。这里假设要改用拥塞避免算法。
4 发送方开始执行拥塞避免算法 发送方的拥塞窗口不会成倍或以较快的速度的增加,而是以一种较小的速率去增加拥塞窗口大小。 接受方对结果进行回复确认 发送方根据动态改变的发送窗口大小发送数据。
5 发送方发现拥塞 发送方没有收到接收方的确认回复 接收方没有收到数据包或者回复数据包被丢失 慢开始门限会直接设置为拥塞时的发送窗口值的一半(它是存在一个最小值的),拥塞窗口直接降为初始值开始执行慢开始算法。
6 执行序号2后使用快重传算法 发送方正常发送数据 接收方每收到一个失序的报文段就会立即发出重复确认。  这样接收方就能很快的知道有数据段没有正确的被接收方接受。快重传规定只要接收方连续收到三个重复确认就会赶快重传确认数据包里说明的下一个数据段,而不是等待为丢失报文设置的计时器。
 7  执行快重传算法时会同时执行快恢复算法  现在发送方收到3个重复确认  接收方继续监听数据  发送方会将慢开始门限ssthresh减半,这是为了预防网络发送拥塞,因为发送方没有及时收到正确的数据段序号很有可能是网络出现拥塞。接着不会执行慢开始算法,即不会将拥塞窗口值降为初始值而是为此时ssthresh的数值。

声明:本文原创发表于博客园,作者为方小白,如有错误欢迎指出 。本文未经作者许可不许转载,否则视为侵权。

浅入tcp的更多相关文章

  1. Flink 反压 浅入浅出

    前言 微信搜[Java3y]关注这个朴实无华的男人,点赞关注是对我最大的支持! 文本已收录至我的GitHub:https://github.com/ZhongFuCheng3y/3y,有300多篇原创 ...

  2. 浅入Kubernetes(11):了解 Service 和 Endpoint

    目录 Srevice Service 的创建及现象 Service 定义 Endpoint slices 创建 Endpoint.Service Service 创建应用 创建 Endpoint 浅入 ...

  3. 浅入Kubernetes(8):外网访问集群

    目录 查询 Service Service 外部服务类型 配置 ServiceType 伸缩数量 阶段总结 在前面几篇文章中,我们学习了 kubeadm .kubectl 的一些命令,也学会了 Dep ...

  4. 浅入浅出EmguCv(三)EmguCv打开指定视频

    打开视频的思路跟打开图片的思路是一样的,只不过视频是由一帧帧图片组成,因此,打开视频的处理程序有一个连续的获取图片并逐帧显示的处理过程.GUI同<浅入浅出EmguCv(二)EmguCv打开指定图 ...

  5. 浅入浅出EmguCv(一)OpenCv与EmguCv

    最近接触计算机视觉方面的东西,于是准备下手学习opencv,从官网下载windows的安装版,配置环境,一系列步骤走完后,准备按照惯例弄个HelloWord.也就是按照网上的教程,打开了那个图像处理领 ...

  6. 浅入深出之Java集合框架(上)

    Java中的集合框架(上) 由于Java中的集合框架的内容比较多,在这里分为三个部分介绍Java的集合框架,内容是从浅到深,如果已经有java基础的小伙伴可以直接跳到<浅入深出之Java集合框架 ...

  7. 浅入深出之Java集合框架(中)

    Java中的集合框架(中) 由于Java中的集合框架的内容比较多,在这里分为三个部分介绍Java的集合框架,内容是从浅到深,如果已经有java基础的小伙伴可以直接跳到<浅入深出之Java集合框架 ...

  8. 浅入深出之Java集合框架(下)

    Java中的集合框架(下) 由于Java中的集合框架的内容比较多,在这里分为三个部分介绍Java的集合框架,内容是从浅到深,哈哈这篇其实也还是基础,惊不惊喜意不意外 ̄▽ ̄ 写文真的好累,懒得写了.. ...

  9. 浅入深出Vue:环境搭建

    浅入深出Vue:环境搭建 工欲善其事必先利其器,该搭建我们的环境了. 安装NPM 所有工具的下载地址都可以在导航篇中找到,这里我们下载的是最新版本的NodeJS Windows安装程序 下载下来后,直 ...

随机推荐

  1. 【【模板】严格次小生成树[BJWC2010]】

    树上的路径怎么能没有树剖 显然,次小生成树和最小生成树只在一条边上有差距,于是我们就可以枚举这一条边,将所有边加入最小生成树,之后再来从这些并不是那么小的生成树中找到那个最小的 我们往最小生成树里加入 ...

  2. EF和linq to sql 关系

    LINQ to SQL 允许你用任何类来代表数据库中的数据.表.同样的,EF也允许你用任何类来代表苏据库中的数据.表. 所不同的的地方是Linq to sql 用这些被修饰过的类直接同数据库打交道,存 ...

  3. 关于tomcat无法启动问题详解

    通常情况tomcat无法启动,有这么几个原因?(1)代码有问题; (2)tomcat有问题; (3)端口被占; (4)动态web项目为3.0: (5)java环境运行内存不足; 这是比较常见的问题.解 ...

  4. Apollo深度磁盘清理

    摘要 在Apollo的使用过程中,会出现磁盘空间不足的情况,Apollo的官方提供的方法是删除apollo/data/log或者删除apollo/data/bag文件.但是即使删除了这些,磁盘空间并没 ...

  5. [转]Ribbon界面介绍(1)

    小弟最近在学习VS2010中Ribbon界面的介绍,相比与C#的界面设计的强大,C++的界面实在太难做了,但没办法,项目需求,又不得不做,遍查网络上的资料,发现有用的基本上就是MSDN的帮助,又是全英 ...

  6. [NOIP2016]换教室(概率期望$DP$)

    其实吧我老早就把这题切了--因为说实话,这道题确实不难啊--李云龙:比他娘的状压DP简单多了 今天我翻以前在Luogu上写的题解时,突然发现放错代码了,然后被一堆人\(hack\)--蓝瘦啊\(ORZ ...

  7. 如何处理Entity Framework / Entity Framework Core中的DbUpdateConcurrencyException异常(转载)

    1. Concurrency的作用 场景有个修改用户的页面功能,我们有一条数据User, ID是1的这个User的年龄是20, 性别是female(数据库中的原始数据)正确的该User的年龄是25, ...

  8. 记一次 oracle 12.2 RAC : Transaction recovery: lock conflict caught and ignored

    节点一 alert日志: PDB(17):Transaction recovery: lock conflict caught and ignored PDB(17):Transaction reco ...

  9. orcal 数据库 maven架构 ssh框架 的全xml环境模版 及常见异常解决

    创建maven项目后,毫不犹豫,超简单傻瓜式搞定dependencies(pom.xml 就是maven的依赖管理),这样你就有了所有你要的包 <project xmlns="http ...

  10. 一次tomcat的调优记录

    项目本身需要上传模型,使用的是springboot1.5.3. 上传的模型比较大,下载的过程中就出现了问题(下载是su调用的java接口,其开发并非本人负责,不可更改) 问题在于,下载的时候tomca ...