写点什么

TCP_UDP 协议详解,大牛带你直击优秀开源框架灵魂

用户头像
Android架构
关注
发布于: 2021 年 11 月 05 日


UDP 首部字段很简单,由 4 个字段组成,每个字段的长度都是两个字节,共 8 字节。


  • 源端口 原端口号,在需要对方回信时选用,不需要时可全 0

  • 目的端口 目的端口号,这在终点交付报文时必须使用,不然数据交给谁呢?

  • 长度 UDP 的长度,最小值为 8 字节,仅有首部

  • 检验和 检测用户数据报在传输过程是否有错,有错就丢弃。


在传输的过程中,如果接收方 UDP 发现收到的报文中的目的端口不存在,会直接丢弃,然后由网际控制报文协议 ICMP 给发送方发送“端口不可达”差错报文。

2、伪首部

计算校验和时,需要在 UDP 之前增加 12 个字节的伪首部。这种首部并不是用户数据报的真正首部。伪首部并不在网络中传输,只是在计算检验和,临时添加在 UDP 用户数据报前,得到一个临时的用户数据报。


UDP 的校验和是把首部和数据部分一起校验,发送方计算校验和的一般步骤:


  1. 将首部的校验和字段填充为 0(零)

  2. 把伪首部和用户数据报 UDP 看出 16 位的字符串连接起来

  3. 如果数据部分不是偶数字节,则填充一个全零字节(该字节不发送到网络层)

  4. 按二进制反马计算出这些 16 位字的和

  5. 然后将和写入校验和字段,就可以发送到网络层了。


接收方收到用户数据报后,连同伪首部一起,按二进制反码求这些 16 位字的和,无差错结果是应全为 1.否则出错,直接丢弃该报文。


TCP 协议

TCP 协议作为传输层主要协议之一,具有面向连接,端到端,可靠的全双工通信,面向字节流的数据传输协议。


《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
浏览器打开:qq.cn.hn/FTe 免费领取
复制代码


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 发送窗口的一半或已达到报文段的最大长度也会立即发送报文段,而不是等待接收方确认。这是为了提高网络吞吐量。

用户头像

Android架构

关注

还未添加个人签名 2021.10.31 加入

还未添加个人简介

评论

发布
暂无评论
TCP_UDP协议详解,大牛带你直击优秀开源框架灵魂