TCP_UDP 协议详解 (1)
TCP 协议
TCP 协议作为传输层主要协议之一,具有面向连接,端到端,可靠的全双工通信,面向字节流的数据传输协议。
1、TCP 报文段
虽然 TCP 面向字节流,但 TCP 传输的数据单元却是报文段。TCP 报文段分为 TCP 首部和数据部分,TCP 报文段首部的前 20 个字节是固定的,后面有 4*n 字节根据需要动态添加的选项,最大长度为 40 字节。
源端口和目的端口 各占两个字节,TCP 的分用功能也是通过端口实现的。
序号 占 4 个字节,范围是[0,232],TCP 是面向字节流的,每个字节都是按顺序编号。例如一个报文段,序号字段是 201,携带数据长度是 100,那么第一个数据的序号就是 201,最后一个就是 300。当达到最大范围,又从 0 开始。
确认号 占 4 个字节,是期望收到对方下一个报文段的第一个字节的序号。若确认号=N,则表示序号 N 前所有的数据已经正确收到了。
数据偏移 占 4 位,表示报文段的数据部分的起始位置,距离整个报文段的起始位置的距离。间接的指出首部的长度。
保留 占 6 位,保留使用,目前为 0.
URG(紧急) 当 URG=1,表明紧急指针字段有效,该报文段有紧急数据,应尽快发送。
ACK(确认) 仅当 ACK=1 时,确认号才有效,连接建立后,所有的报文段 ACK 都为 1。
PSH(推送) 接收方接收到 PSH=1 的报文段,会尽快交付接收应用经常,不再等待整个缓存填满再交付。实际较少使用。
RST(复位) RST=1 时,表明 TCP 连接中出现严重差错,必须是否连接,再重连。
SYN(同步) 在建立连接时用来同步序号。当 SYN=1,ACK=0,则表明是一个连接请求报文段。SYN=1,ACK=1 则表示对方同意连接。TCP 建立连接用到。
FIN(终止) 用来释放一个连接窗口。当 FIN=1 时,表明此报文段的发送方不再发送数据,请求释放单向连接。TCP 断开连接用到。
窗口 占 2 个字节,表示发送方自己的接收窗口,窗口值用来告诉对方允许发送的数据量。
校验和 占 2 字节,检验和字段查验范围包括首部和数据部分。
紧急指针 占 2 字节,URG=1 时,紧急指针指出本报文段中的紧急数据的字节数(紧急字节数结束后为普通字节)。
选项 长度可变,最长可达 40 字节。例如最大报文段长度 MSS。MSS 指的是数据部分的长度而不是整个 TCP 报文段长度,MSS 默认为 536 字节长。窗口扩大,时间戳选项等。
2、TCP 建立连接-三次握手
三次握手图例如下,与文字解释配合使用效果更佳。
第一次:客户端发送连接请求报文给服务端,其中 SYN=1,seq=x。发送完毕后进入 SYN_END 状态。
第二次:服务端接收到报文后,发回确认报文,其中 ACK=1,ack=x+1,因为需要客户端确认,所以报文中也有 SYN=1,seq=y 的信息。发送完
后进入 SYN_RCVD 状态。
第三次:客户端接收到报文后,发送确认报文,其中 ACK=1,ack=y+1。发送完客户端进入ESTABLISHED
状态,服务端接收到报文后,进入ESTABLISHED
状态。到此,连接建立完成。
三次握手原因
避免资源被浪费掉。如果在第二步握手时,由于网络延迟导致确认包不能及时到达客户端,那么客户端会认为第一次握手失败,再次发送连接请求,服务端收到后再次发送确认包。在这种情况下,服务端已经创建了两次连接,等待两个客户端发送数据,而实际却只有一个客户端发送数据。
3、TCP 断开连接-四次挥手
四次挥手指客户端和服务端各发送一次请求终止连接的报文,同时双方响应彼此的请求。 四次挥手图例如下,请配置文字解释使用哦。
第一次挥手:客户端发送 FIN=1,seq=x 的包给服务端,表示自己没有数据要进行传输,单面连接传输要关闭。发送完后,客户端进入FIN_WAIT_1
状态。
第二次挥手:服务端收到请求包后,发回 ACK=1,ack=x+1 的确认包,表示确认断开连接。服务端进入CLOSE_WAIT
状态。客户端收到该包后,进入FIN_WAIT_2
状态。此时客户端到服务端的数据连接已断开。
第三次挥手:服务端发送 FIN=1,seq=y 的包给客户端,表示自己没有数据要给客户端了。发送完后进入LAST_ACK
状态,等待客户端的确认包。
第四次挥手:客户端收到请求包后,发送 ACK=1,ack=y+1 的确认包给服务端,并进入TIME_WAIT
状态,有可能要重传确认包。服务端收到确认包后,进入CLOSED
状态,服务端到客户端的连接已断开。客户端等到一段时间后也会进入CLOSED
状态。
四次挥手原因 由于 TCP 的连接是全双工,双方都可以主动传输数据,一方的断开需要告知对方,让对方可以相关操作,负责任的表现。
使用 TCP 协议有:FTP(文件传输协议)、Telnet(远程登录协议)、SMTP(简单邮件传输协议)、POP3(和 SMTP 相对,用于接收邮件)、HTTP 协议等
4、TCP 流量控制
滑动窗口协议
TCP 滑动窗口协议主要为了解决在网络传输数据的过程中,发送方和接收方传输数据速率不一致的问题,从而保证数据传输的可靠性,达到流量控制的效果。 发送方中的数据分为三种:
发送已确认
发送未确认
未发送
接收方数据分为三种:
已接收和确认但未被上层读取
接收未确认
在发送方的滑动窗口中,可分为发送窗口和可用窗口。发送窗口中的数据已发送接收方,但未接到接收方的确认;可用窗口则表示发送方还可以发送多少数据。发送方的窗口大小会受到接收方窗口的改变而改变。
利用滑动窗口机制能有效的控制发送方的发送数据速率。下面是个栗子:
TCP 的窗口单位是字节,不是报文端,所以上文假设一个报文包含 100 个字节。ACK 是确认位,ack 是确认号,seq 是序列号,对应报文的数据格式的。A 和 B 在 TCP 三次握手时候,B 会告诉 A 自己的接收窗口 rwnd 大小。上图中,A 向 B 先发送了三次数据,但第三次丢失了,同时受到 B 的流量控制,当前 ack=201,还需允许继续发送序号为 201 到 500 共 300 个字节。当 A 发送到序号为 500 时,就不能发新的数据了,但能接收第三次丢失的数据。
接收方数据被上层读取后,又可以接收序号为 501-600 共 100 个字节,所以通知 A,接收窗口大小为 100,序号为 501 开头....在上图的整个过程中,A 共收到 B 三次流量控制。
TCP 报文段发送的机制
应用层把数据传递给传输层的 TCP 的发送缓存后,TCP 通过不同的机制来控制报文段的发送时机。 主要有下面三种机制:
TCP 维护一个变量,等于最大报文段长度 MSS,缓存中存放的数据达到 MSS 字节时,则以一个报文段发送出去。
发送应用层指明要求的报文段,即 TCP 支持的推送操作。
发送法计时器期限到了,就要把前面缓存的数据以报文段发送出去,前提是长度不能超过 MSS。
TCP 传输效率问题
不同的发送机制都会带来一定的效率问题,例如用户发送一个字符,加上 20 字节首部,得到 21 字节长的 TCP 报文段,再加上 21 字节的 IP 首部,就变成 41 字节长的 IP 数据报。发送一个字节,线路上就需要发送 41 字节长的 IP 数据报,若等待接收方确认,线程就又多了 40 字节长的数据报。所以在线程带宽不富裕时,这种传输效率非常不高。因此应当推迟发回确认报文,并尽量使用捎带确认的方法。
Negle 算法
Negle 算法主要为了解决 TCP 的传输效率问题。Negle 算法规定:若要把发送的数据逐个字节缓存起来,则发送方需要把第一个字节发送出去,然后缓存后面的字节,在收到接收方第一个字节的确认,再将现有缓存中所有字节组成一个报文段发送出去,继续缓存后续数据。只有在收到前一个报文的确认之后发送后面的数据。这是为了减少所用带宽。当发送数据到达 TCP 发送窗口的一半或已达到报文段的最大长度也会立即发送报文段,而不是等待接收方确认。这是为了提高网络吞吐量。
糊涂窗口综合征
TCP 接收方的缓存已满,若上层一次从缓存中读取一个字节,这样接收方就可以继续接纳一个字节的窗口,然后向发送方发送确认,把窗口设为 1 个字节(上文所讲,IP 数据报为 41 字节长)。如果这样持续下去,那么网络效率非常低。
所以有效的解决方法,就是让接收方等待一定时间,让缓存空间能够接纳一个最长的报文段,或者等待接收缓存已有一半的空闲空间,再发出确认报文和通知当前窗口大小。
5、TCP 的拥塞控制
拥塞
什么是拥塞呢,在某段时间,若对网络中某一资源的需求超过了该资源所能提供的可用部分,网络性能就会变坏了,这种情况就叫拥塞。网络资源常指网络链路容量(带宽)、交换结点中的缓存和交换处理机。
当出现拥塞,条件允许一般都是通过添加网络资源,例如带宽换成更大的,但这治标不治本,而且不一定总是有用。网络拥塞往往是有许多因素引起的,因此就需要拥塞控制了。
拥塞控制
拥塞控制指防止过多的的数据注入到网络中,这样可以使网络中的路由器或链路不过载。拥塞机制是一个全局性的过程,涉及到所有主机、所有路由器,以及与降低网络传输性能有光的所有因素。
而滑动窗口协议的流量控制,是指点到点的通信量控制,是端到端的问题。
TCP 的拥塞控制方法
TCP 进行拥塞控制的算法有四种:慢开始、拥塞避免、快重传、快恢复。
拥塞控制是基于拥塞窗口的,发送方维持一个拥塞窗口 cwnd 的状态变量。窗口大小取决网络的拥塞程度,并且动态变化,发送方会让自己的发送窗口等于拥塞窗口。判断网络拥塞的依据就是发送方接收接收方的确认报文是否超时。
1、慢开始算法
慢开始指主机由小到大逐渐增大发送窗口,即增大拥塞窗口的数值。初始拥塞窗口 cwnd 设置为不超过 2 到 4 个最大报文段 SMSS 的数值,具体规定:
若 SMSS≤1095 字节,cwnd=4 x SMSS 字节,不得超过 4 个报文段。
若 SMSS>1095 且≤2190 字节,cwnd=3 X SMSS 字节,不得超过 3 个报文段。
若 SMSS>2190 字节,则 cwnd=2 x SMSS 字节,不得超过 2 个报文段。
从上面的规定限制了初始拥塞窗口的大小。
慢开始在每收到一个对新的报文段的确认后,cwnd 就可以增加最多一个 SMSS 的数值。
N 是刚收到确认的报文段所确认的字节数,当 N<SMSS 时,拥塞窗口每次的增加量要小于 SMSS。下文举例说明慢开始的原理(实际上,TCP 的窗口是以字节大小为单位,下文为了方便以报文端形容):
从图可知,初始化窗口未 1,所有发送 M1 报文段,收到确认号之后,发送 M2-M3 两个报文段,因为拥塞窗口增大了,后面的轮次也是这样翻倍增加的。随着轮次的增多,那么发送到网络的数据就会急剧增加,容易出现拥塞,因此需要慢开始门限(ssthresh)状态变量。
当 cwnd<ssthresh 时,使用慢开始算法
当 cwnd>ssthresh 时,使用拥塞避免算法
评论