TCP_UDP 协议详解,大牛带你直击优秀开源框架灵魂
UDP 首部字段很简单,由 4 个字段组成,每个字段的长度都是两个字节,共 8 字节。
源端口 原端口号,在需要对方回信时选用,不需要时可全 0
目的端口 目的端口号,这在终点交付报文时必须使用,不然数据交给谁呢?
长度 UDP 的长度,最小值为 8 字节,仅有首部
检验和 检测用户数据报在传输过程是否有错,有错就丢弃。
在传输的过程中,如果接收方 UDP 发现收到的报文中的目的端口不存在,会直接丢弃,然后由网际控制报文协议 ICMP 给发送方发送“端口不可达”差错报文。
2、伪首部
计算校验和时,需要在 UDP 之前增加 12 个字节的伪首部。这种首部并不是用户数据报的真正首部。伪首部并不在网络中传输,只是在计算检验和,临时添加在 UDP 用户数据报前,得到一个临时的用户数据报。
UDP 的校验和是把首部和数据部分一起校验,发送方计算校验和的一般步骤:
将首部的校验和字段填充为 0(零)
把伪首部和用户数据报 UDP 看出 16 位的字符串连接起来
如果数据部分不是偶数字节,则填充一个全零字节(该字节不发送到网络层)
按二进制反马计算出这些 16 位字的和
然后将和写入校验和字段,就可以发送到网络层了。
接收方收到用户数据报后,连同伪首部一起,按二进制反码求这些 16 位字的和,无差错结果是应全为 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 发送窗口的一半或已达到报文段的最大长度也会立即发送报文段,而不是等待接收方确认。这是为了提高网络吞吐量。
评论