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. jq实现多级菜单

    <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...

  2. android中反射技术使用实例

    在计算机科学领域.反射是指一类应用,它们能够自描写叙述和自控制.也就是说,这类应用通过採用某种机制来实现对自己行为的描写叙述(self-representation)和监測(examination), ...

  3. 2018-2019-2 网络对抗技术 20165322 Exp4 恶意代码分析

    2018-2019-2 网络对抗技术 20165322 Exp4 恶意代码分析 目录 实验内容与步骤 系统运行监控 恶意软件分析 实验过程中遇到的问题 基础问题回答 实验总结与体会 实验内容与步骤 系 ...

  4. nordic对苹果性能测试

    环境: app采用nrf connect或lightblue均可: nordic从端采用nrf52840开发板pca10056: 说明与规定: (1)鉴于手机app无法主动连续快速发送多包数据,故只测 ...

  5. c++ 有swap函数

    这是剑指offer数组中重复的数字那个题,直接使用的swap函数 class Solution { public: // Parameters: // numbers: an array of int ...

  6. 初始化列表initializer_list

    初始化列表定义在<initializer_list>,初始化列表简化了参数数量可变的函数的编写,初始化列表的所有的元素都应该是同一种数据类型 由于定义了列表中允许的类型,所以初始化列表是安 ...

  7. java从字符串中提取数字的简单实例

    随便给你一个含有数字的字符串,比如: String s="eert343dfg56756dtry66fggg89dfgf"; 那我们如何把其中的数字提取出来呢?大致有以下几种方法, ...

  8. HDU 1165 Eddy's research II(给出递归公式,然后找规律)

    - Eddy's research II Time Limit:2000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64 ...

  9. HDU 1829 A Bug's Life (种类并查集)

    传送门: http://acm.hdu.edu.cn/showproblem.php?pid=1829 A Bug's Life Time Limit: 15000/5000 MS (Java/Oth ...

  10. stateless 无状态组件

    使用: