原创

TCP的漫想

一、一个数据包

路是通的, 而且是双向通的。所以会有tcp的三次握手确认包。一次客户端的syn+一次客户端ack包 = 客户端到服务端的路是通的,反过来亦是如此。TCP涉及阶段:CLOSED, LISTEN, SYN-RECEIVED, SYN-SENT.

1.1 syn包丢失

如果意外情况发生呢。假设客户端到服务端syn包丢失呢。(tcp状态机 切换有个超时时间)。重发间隔有多长,这个时间是数据的ACK包能在这个时间内返回。但是不同的网络环境这个时间也不一样。所以TCP实现的是一个动态的计算时间。每次发包都会计算RTT和偏差值。

1.1.1重传间隔

设定的重发时间间隔会比RTT+偏差的上限略高点。网络包的RTT偏差或者抖动其实是由分段经过不同的路径到达。

如果最初的没有计算,会有个初始值,一般是6s(在哪里查看?)。同时unix的一般最少是0.5s的整数倍。

1.1.2 重传次数和时间限制

问题又来了,如果重发也没用,或许网络真的故障了,那一直按这个时间间隔重传,或者有最多的retry次数吗?后续等待应答的重传时间是以指数级增长,并且有一定最多次数,毕竟超过这个最大限制,网络基本大概率就是不可用的状态。

1.1.3 syn flood攻击

tcp握手完成至此已经建立连接。并处以establiched状态,可能如果syn包在路上丢失呢,如果客户端收到故意不回呢?(syn flood攻击)。因为这个连接标识着(是否在双方机器都有维护一个状态。)tcp连接维护的开销在内核中。

1.2 ack(确认syn)包丢失

假如syn包到底服务端,服务端发送ack包给客户端呢。丢失呢,服务端发送ack包给客户端。第三个握手包(ACK)只关乎是否已经收到第二个握手的syn包,所以只要后面带数据的ack,能ack到syn包,应该没问题

1.2.1 TCP FAST OPEN

. 那既然能发ack,为什么不和后面的数据包一起发送呢,这样相当于2个RTT之后就进入数据传输阶段。如果开启了TCP fast open确实可以这样。但是这是一个可选功能。

1.2.2 伪造ack序列号或者缺失序列号

TCP:遇到非法、伪造的syn的ack包,会做什么处理。或者没有携带序列号,或者序列号不对,这些协议栈都是不会建立连接的。

1.2.3 四次握手

还有个问题服务端的SYN和ACK可以分开发吗。比如这种双方都主动打开,当然也是有可能的,这个就是四次握手。

四次握手

1.3 连接创建后:

1.3.1 URG位需要紧急处理的数据

URG对应的URG数据指针,从数据部分的首位到紧急指针所指向的位置为止都为紧急数据。那么应用一般什么情况会触发紧急数据呢,一般在暂停通信的场合用的多,比如浏览器的停止按钮,telnet的ctrl+c

二、多个数据包

2.1 大数据包分组

如果是大数据包怎么办,TCP数据还是得依托IP层发送,所以IP层的分组是有控制的,分片太小容易引人多余的IP头带宽开销,所以这个最大消息长度(MSS,Max Segment Size)就是以IP层分片载荷的最大大小。

这个MSS在TCP建连协商中会进行沟通。双方会取最小值。

每个数据包大小也不一样。无限长或者不知道长度的数据包怎么办?联想到http的chunk协议。同样地tcp也是用基本单位来确定 数据包。每次读到MSS(Max Segment Size)。每片MSS带有唯一的序号,在发送或者数据丢失重发是最小的单位。MSS多大呢,当然得是同时满足双方的最大要求,这得益于双方syn包建立创建的协商双方协商的最小。

2.2 有序

多个数据包肯定是有序的(后面发送的内容 接收端不能提前到)。方法是给每个数据包编号。

2.2.1 一次发送一次ACK

接下来怎么保证有序性呢,最简单的想法就是一次发送,一次ack,这样保证前面的肯定是已经确认发送成功的数据。这个就有个问题了,假设双方的通信距离很长,那么一次发送一个分片数据,至少等一个RTT。发送端发完数据包,就是无尽的等待ack的到来。

2.2.2 滑动窗口

改善的窗口,一次可以发送多个分片数据,并且最快只需要等待接近一个RTT的时间确认这一坨多片数据全部被接收到。问题来了,如果窗口内数据乱序怎么办,如果数据部分丢失怎么办(tcp接收端源码是怎么实现的,控制这个逻辑)

增强型的部分ack,窗口内的数据只需要传输最大的那片ack。最大的那片ack代表以前的序号全部被接收完全。

2.3 丢失保障

2.3.1快速重传机制

如果某个包丢失了,那么当tcp收到的包不是他期待的那个序号,那么他会发一个期待的ack给发送端(此时应该是第二遍发送这个序号的包了,第一次这个序号是正常的,不包括这次算3次,乱序和重传的差别,为什么是3次,有可能是乱序造成的重传,2次必定是乱序)。那么发送端如果连续两次,会重发吗,为什么会,为什么不会?如果继续收到

2.3.2 乱序

由于接收端性能原因,丢包或者乱序,或者应用程序延迟响应,数据丢失造成带宽浪费。所以有一种机制让发送端发送接收端所能接收的数据流。流控制。窗口大小包,更新窗口大小值。窗口探测包。

2.3.3 其他手段:

慢启动解决拥塞问题。

ngeal算法,延迟确认应答,捎带应答

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 原来你是这样的http2

    目前HTTP/2.0(简称h2)已经在广泛使用(截止2018年8月根据Alexa流行度排名的头部1千万网站中,h2占比约29%,https://w3techs....

    mariolu
  • 惊群效应

    传统的服务器使用“listen-accept-创建通信socket”完成客户端的一次请求服务。在高并发服务模型中,服务器创建很多进程-单线程(比如apache ...

    mariolu
  • MAC工作机提升工作效率的tips

    MAC和Windows环境不一样。Window靠着资源管理器explorer.exe,并且提供桌面环境和shell工具比如xshell。工作环境切换到MAC,M...

    mariolu
  • 移动视频聚合应用法律问题分析

    腾讯公司法务综合部法律顾问 刘青 腾讯研究院法律研究中心 田小军 摘要: “注意力”经济之下,各大视频网站逐渐加大对优质视频版权采购、服务器与带宽扩容等...

    腾讯研究院
  • Java面试题—基础题目

    在并发编程领域,有进程和线程两个概念,在Java语言中说起并发编程,常常是指多线程,但是了解进程的概念也非常重要:

    阿杜
  • 使用truffle部署以太坊智能合约到区块链

    truffle是以太坊(ethereum)开发智能合约(smart contract)过程中最受欢迎的框架,本教程来安装构建一个基本的Truffle项目并部署一...

    笔阁
  • 单元测试

      每个开发人员都写过很多代码、函数,但是你能保证你写的每个函数都能执行并且正常吗?   我们太多时间站在功能需求的角度来审视我们的代码,认为需求实现功能逻辑...

    OPice
  • 大举扩张的Airbnb,或将重走Uber老路

    镁客网
  • 程序员精神崩溃怎么办?九大建议巧应对

    我是攻城师
  • python实现单链表

    py3study

扫码关注云+社区

领取腾讯云代金券