TCP“粘包”
首先需要明白,“TCP 粘包”这个称呼本身是有问题的,因为 TCP 是面向字节流的协议 ,不存在数据边界,所以 TCP 本身就不会有什么“粘包”的问题。要说“粘包”,这个词更适合形容 UDP 这类 面向数据报 的协议。所以说,“粘包”并不是 TCP 的范畴,而是程序员基于错误的理解来实现上层逻辑,从而导致的问题,和 TCP 本身无关。再具体而言,“TCP粘包问题”应该阐述为——在TCP传输协议下,应用层数据拼装发送和接收解析的问题 。不过为了方便描述,下文就采用“TCP粘包”一词。
粘包如何产生?
“粘包”的首要原因就是 基于字节流 这个特点。字节流可以理解为一个双向的通道里流淌的数据,这个数据其实就是我们常说的二进制数据,简单来说就是一大堆 01 串,而这些 01 串之间 没有任何边界 。应用层传到 TCP 协议的数据以字节流的方式发送到下游,这些数据可能被切割(过大)和组装(过小)成段,接收端收到这些段后没有正确还原原来的消息,因此出现粘包现象。粘包可以发生在发送端和接收端。
发送端:
在 Nagle 算法(参考此处)开启的状态下,数据包在以下两个情况会被发送:
如果包长度 ...
TCP拥塞控制详解(一)
什么是网络拥塞?
当 TCP 数据包经由网络中的路由器传输的时候,如果路由器的收包速度大于处理速度,路由器一般会先把收到的数据包缓存起来等待后续处理。但是当网络传输速度过大时,则会导致路由器的缓存空间全部被占用从而只能丢弃一部分数据包,如果一个路由器或者交换机等网络节点由于性能或者带宽等因素的限制而不能及时处理这些业务数据的时候,就会强制丢包,这种场景就叫做 拥塞(congestion) 。
拥塞控制和流量控制的关系?
流量控制是点对点通信量的控制,是端到端的问题。流量控制所要做的就是抑制发送端发送数据的速率,以便使接收端来得及接收;拥塞控制是防止过多的数据注入到网络中,这样可以使网络中的路由器或链路不致过载。拥塞控制是一个全局性的过程,关注到传输链路上所有的主机、路由器,以及与降低网络传输性能有关的所有因素。
流量控制是以显式的方式在TCP头中通过 Window size 字段通告发送方,流量控制关注的是接收端和发送端;拥塞控制大多是通过隐式的方式控制发送端速率,接收端依据特定的收发包情况来推测网络拥塞状况 。
简单而言,流量控制考虑的是接收方的接收能力,拥塞控制考虑的是网 ...
TCP流量控制详解
滑动窗口
TCP 流量控制基于 滑动窗口 (连续 ARQ 协议) 实现。滑动窗口既保证了分组无差错、有序接收,也实现了流量控制。
发送方的滑动窗口由接收方控制,实现方法为:在接收方传递给发送方的报文中加入 Window Size 信息,从而告知发送方自己的窗口大小,且发送方必须服从接收方的管理 。在 TCP 实现中,两端的窗口大小相同 。另外需要注意的是,发送方不一定会一次性发送整个窗口的数据,这根据网络情况而定。
窗口本身是一种抽象 ,发送窗口有三个变量实现,分别为:SfS_fSf (第一个未完成分组)SnSnSn (下一个待发送分组)SsizeS{size}Ssize (窗口大小)。
一般而言,流量控制分为两种:1)发送方输出的流量过多,接收方来不及接收。2)发送方发得太少,导致浪费带宽(数据只有一两个字节,而报头就占了几十个字节)。对于第一种则很好控制,只要发送方将每次输出的流量控制在接收方告知的窗口大小内即可;对于第二种情况(被称之为 糊涂窗口综合征 ),则相对复杂。
糊涂窗口综合征 :当发送端进程产生数据缓慢或接收端进程数据拉取缓慢时,会导致发送方以很小的段发送 ...
TCP重传机制详解
超时重传
超时重传基于定时器,以时间驱动重传 。当发送端发送数据包后会启动相应计时器,如果在一定时间内未收到接收端发来的 ACK 报文导致计时器超时,则会重传相应报文。
需要注意的是,是仅重发相应超时报文还是重发所有未完成(已发出但未收到 ACK)的报文,在各个机制中有所不同(这取决于定时器的数量)。比如在【停等协议】中, 仅有一个定时器,一旦超时,重发所有未完成包;而在【选择重传协议】中,每个报文都有一个定时器,超时后仅重传对应报文。详细内容见:详解ARQ协议
超时重传面临三个主要问题:
RTO(重传时间) 如何确定?
超时才发生重传,延迟较高。
发生超时后,重传哪些包?
比如,发送端按序发送 1,2,3,4,5 个包,发送端只接收到第 1,2,4,5个包,那么接收端只能发送 ACK = 3 的 ACK 报文(表明 3 之前的都已收到),发送端收到 ACK 报文后,定时器超时, 由于此时第 3,4,5 的 ACK 报文都没有收到,那么发送端该重发哪些报文呢?只发 3 的报文还是发送 3,4,5 的报文?前者会节省带宽,但是若 4,5 真的也丢失了,又会等待重传;后者 ...
TCP握手优化:T/TCP与TFO
当前 web 和 web-like 应用中一般都是在三次握手后开始数据传输,相比于 UDP,多了一个 RTT 的时延,即使当前很多应用使用 长连接 来处理这种情况,但是仍然有一定比例的 短连接 ,这额外多出的一个 RTT 仍然对应用的时延有非常大的影响。T/TCP 和 TFO 就是在这种背景下面提出来的。
点击此处:什么是短链接与长连接?
什么是 T/TCP?
T/TCP 是基于事务的 TCP,“事务” 是指类似与 http 和 DNS 这类连接持续很短的请求-回复型应用。对于这类应用,往往客户端只会发送一次数据请求,然后服务器回复一次请求,然后连接就结束了。而建立连接的过程就需要三次握手,由此看来,一般 TCP 对于这类事务的数据传送效率是很低的。T/TCP 就是为了解决这个问题而被提出——直接在 SYN 报文中传递数据。T/TCP 能够把 SYN 、FIN、SYN 合并到一个报文中(前提是数据量必须小于 MSS),从而完成一次对话只需要三次传递:
不过,由于将 SYN 和数据合并发送存在极大的安全隐患,所以这种方式并未得到推广,大多数操作系统也并不支持。因此本文就不对 T/T ...
RTT的测量(RTTM)
我们直到,重传机制是 TCP 协议中一种重要的通信保障手段。在超时重传下,当重传计时器超过 RTO (Retransmission Time Out) 时就会终止计时器并重发。而其中 RTO 是基于 RTT (Round-Trip Time)得到的,那么 RTT 又是如何得到的呢?似乎看起来很简单,好像就是在发送端发包时记下 T0T_0T0 ,接收到 ACK 报时再记一个 T1T_1T1 ,于是 RTT=T1–T0RTT = T_1 – T_0RTT=T1–T0 。没那么简单,这只是一个采样,不能代表普遍情况。
Jacobson / Karels 算法
我们需要采样一些 RTT,称为 SampleRTT 。需要注意, SampleRTT 与单个分组没有一一对应的关系,由于 延迟确认 的存在,两个确认可能合并为一个 ACK 包。SampleRTT 可能随网络情况而波动,任何值都可能是不典型的,所以直接使用 SampleRTT 是不可靠的。
为了估计一个典型的 RTT,自然想到对 SampleRTT 求平均(加权平均),得到平滑RTT(RTTSRTT_SRTTS) ...
时间戳——RTTM与序列号回绕
时间戳格式
时间戳(TimeStamp—TSOPT)选项格式如下:
123456// Kind: 8// Length: 10 bytes// +-------+-------+---------------------+---------------------+// |Kind=8 | 10 | TS Value (TSval) |TS Echo Reply (TSecr)|// +-------+-------+---------------------+---------------------+// 1 1 4 4
TSval 表示发送端发出该报文时的本地时间戳, 而 TSecr 则负责回放 (Echo) 最近一次收到的对端报文中的 TSval 的值。下面是一组典型的时间戳交互过程:
123456789// TCP A ...
SYN泛洪攻击
什么是 SYN 泛洪攻击?
SYN 洪水(半开连接攻击)是一种拒绝服务 (DDoS) 攻击 ,旨在耗尽可用服务器资源,致使服务器无法传输合法流量。通过 TCP 三次握手时,重复发送初始连接请求 (SYN) 数据包,攻击者将占满目标服务器上的所有 半连接队列 ,导致服务器在响应合法流量时表现迟钝乃至全无响应。
SYN 泛洪攻击原理?
攻击者通常使用伪造的不同的 IP 地址向目标服务器发送大量 SYN 数据包。
然后,服务器分别对每一项连接请求做出响应(发送 ACK+SYN 包),并确保打开的端口做好接收响应的准备。
在服务器等待最后一个 ACK 数据包(永远不会到达)的过程中,攻击者将继续发送更多 SYN 数据包,久而久之就会占满服务端各个端口的 半连接队列 ,使得服务器不能为正常用户服务。
半连接队列与全连接队列
正常流程:
当服务端接收到客户端的 SYN 报文时,会将其加入到内核的 SYN 队列(半连接队列) ;
接着发送 SYN + ACK 给客户端,等待客户端回应 ACK 报文;
服务端接收到 ACK 报文后,从 SYN 队列移除放入到 Accept 队列(全连接队列 ...
剖析TCP三握四挥
TCP 协议是 面向连接 的协议,通信前需要先在双端建立 逻辑信道 ,即使是断开连接也不能说断就断,还需双方同意。所以下面我们详细说明 TCP 的连接管理。
在TCP的连接建立过程中一般需要处理下面三个问题
要使每一方能够确知对方的存在。
要允许双方协商一些参数(如最大报文段长度,最大窗口大小,服务质量等)。
能够对传输实体资源(如缓存大小等)进行分配
TCP建立连接最常见的方式就是通过三次握手(three-way handshake) ,连接释放最常见的方式则是 四次挥手(four-way handshake) ,下面我们先介绍这两种最常见的连接管理机制。
三次握手
客户端会随机初始化序号(client_ISN),将此序号置于 TCP 首部的 序号 字段中,同时把 SYN 标志位置为 1 ,表示 SYN 报文。接着把第一个 SYN 报文发送给服务端,表示向服务端发起连接,该报文不包含应用层数据 ,之后客户端处于 SYN-SENT 状态。
服务端收到客户端的 SYN 报文后,首先服务端也随机初始化自己的序号(server_isn),将此序号填入 TCP 首部的 序号 字段 ...
TCP概述及报头解析
TCP 特征概述
TCP 协议在网络 OSI 参考模型中的第四层——传输层,是一个 面向连接的(connection-oriented)、可靠的(reliable)、字节流式的(byte stream) 传输协议。
面向连接 :在应用 TCP 协议进行通信之前,双方通常需要通过三次握手来建立 TCP 连接,连接建立后才能进行正常的数据传输。但是同时面向连接的特性给 TCP 带来了复杂的 连接管理 以及用于检测连接状态的 存活检测机制 。同时,TCP 提供全双工通信。
可靠性 :TCP 层需要解决来自 IP 层的四种常见传输错误问题,分别是 比特错误 (packet bit errors)、包乱序 (packet reordering)、包重复 (packet duplication)、丢包 (packet drops),TCP要提供可靠的传输,就需要有额外的机制处理这几种错误。TCP 通过使用 确认 ,重传 ,校验和 这三种基本机制来实现可靠传输。因此TCP协议具有超时与重传管理、窗口管理、流量控制、拥塞控制等功能。
字节流式 :应用层发送的数据会在 TCP 的发送端缓存起来,统一 ...