持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第20天,点击查看活动详情
UDP
UDP(User Datagram Protocol: 用户数据报协议),是一个非常简单的协议
特点
UDP协议的特点:
- UDP是无连接协议;
- UDP不能保证可靠的交付数据; (即不可靠传输)
- UDP是面向报文传输的;
- UDP没有拥塞控制;
- UDP首部开销很小。
TCP
TCP(Transmission Control Protocol: 传输控制协议),是计算机网络中非常复杂的一个协议。
特点
TCP协议的特点:
- TCP是面向连接的协议;
- TCP是面向字节流的协议;
- TCP的一个连接有两端,即点对点通信;
- TCP提供可靠的传输服务;
- TCP协议提供全双工通信(每条TCP连接只能一对一)
功能
TCP协议的功能:
- 对应用层报文进行分段和重组;
- 面向应用层实现复用与分解;
- 实现端到端的流量控制;
- 拥塞控制;
- 传输层寻址;
- 对收到的报文进行差错检测(首部和数据部分都检错);
- 实现进程间的端到端可靠数据传输控制。
三次握手
为什么需要三次握手?
- 第一次握手:客户发送请求,此时服务器知道客户能发;
- 第二次握手:服务器发送确认,此时客户知道服务器能发能收;
- 第三次握手:客户发送确认,此时服务器知道客户能收。
详细过程
第一次:客户向服务器发送连接请求段,建立连接请求控制段(SYN=1),表示传输的报文段的第一个数据字节的序列号是x,此序列号代表整个报文段的序号(seq=x);客户端进入 SYN_SEND (同步发送状态);
第二次:服务器发回确认报文段,同意建立新连接的确认段(SYN=1),确认序号字段有效(ACK=1),服务器告诉客户端报文段序号是y(seq=y),表示服务器已经收到客户端序号为x的报文段,准备接受客户端序列号为x+1的报文段(ack_seq=x+1);服务器由LISTEN进入SYN_RCVD (同步收到状态);
第三次:客户对服务器的同一连接进行确认.确认序号字段有效(ACK=1),客户此次的报文段的序列号是x+1(seq=x+1),客户期望接受服务器序列号为y+1的报文段(ack_seq=y+1);当客户发送ack时,客户端进入ESTABLISHED 状态;当服务收到客户发送的ack后,也进入ESTABLISHED状态;第三次握手可携带数据;
四次挥手
为什么要四次挥手?
CLOSE-WAIT
客户端发送了 FIN 连接释放报文之后,服务器收到了这个报文,就进入了 CLOSE-WAIT 状态。这个状态是为了让服务器端发送还未传送完毕的数据,传送完毕之后,服务器会发送 FIN 连接释放报文。
TIME-WAIT
客户端接收到服务器端的 FIN 报文后进入此状态,此时并不是直接进入 CLOSED 状态,还需要等待一个时间计时器设置的时间 2MSL。
为什么A在TIME-WAIT状态必须等待2MSL的时间呢?
这么做有两个理由:
- 为了保证A发送的最后一个ACK报文段能够到达B。 A发送的这个ACK报文段有可能丢失,如果 B 没收到 A 发送来的确认报文,那么A就会重新发送连接释放请求报文,A 等待一段时间就是为了处理这种情况的发生。
- 防止“已经失效的连接请求报文段”出现在本链接中。 A在发送完最后一个ACK报文段后,再经过时间2MSL,就可以使本连接的时间内所产生的所有报文段都从网络中消失。这样下一个新的连接中就不会出现这种旧的连接请求报文段。
假设客户端不等待2MSL,而是在发送完ACK之后直接释放关闭,一但这个ACK丢失的话,服务器就无法正常的进入关闭连接状态。
详细过程
第一次:客户向服务器发送释放连接报文段,发送端数据发送完毕,请求释放连接(FIN=1),传输的第一个数据字节的序号是x(seq=x);客户端状态由ESTABLISHED进入FIN_WAIT_1(终止等待1状态) ;
第二次:服务器向客户发送确认段,确认字号段有效(ACK=1),服务器传输的数据序号是y(seq=y),服务器期望接收客户数据序号为x+1(ack_seq=x+1);服务器状态由ESTABLISHED进入CLOSE_WAIT(关闭等待) ;客户端收到ACK段后,由FIN_WAIT_1进入FIN_WAIT_2;
第三次:服务器向客户发送释放连接报文段,请求释放连接(FIN=1),确认字号段有效(ACK=1),表示服务器期望接收客户数据序号为x+1(ack_seq=x+1);表示自己传输的第一个字节序号是y+1(seq=y+1);服务器状态由CLOSE_WAIT 进入 LAST_ACK (最后确认状态) ;
第四次:客户向服务器发送确认段,确认字号段有效(ACK=1),表示客户传输的数据序号是x+1(seq=x+1),表示客户期望接收服务器数据序号为y+1+1(ack_seq=y+1+1);客户端状态由FIN_WAIT_2进入TIME_WAIT,等待2MSL时间,进入CLOSED状态;服务器在收到最后一次ACK后,由LAST_ACK进入CLOSED;
为什么建立连接协议是三次握手,而关闭连接却是四次握手呢?
这是因为服务端的LISTEN状态下的SOCKET当收到SYN报文的连接请求后,它可以把ACK和SYN(ACK起应答作用,而SYN起同步作用)放在一个报文里来发送。但关闭连接时,当收到对方的FIN报文通知时,它仅仅表示对方没有数据发送给你了;但未必你所有的数据都全部发送给对方了, 所以你可能未必会马上会关闭SOCKET,也即你可能还需要发送一些数据给对方之后,再发送FIN报文给对方来表示你同意现在可以关闭连接了,所以它这里的ACK报文和FIN报文多数情况下都是分开发送的。
不可靠传输带来的问题
不可靠传输信道在数据传输中可能发生的情况:比特差错、乱序、重传、丢失
TCP怎么保证可靠性?简述TCP建立连接和断开连接的过程?
-
序列号,确认应答,超时重传
数据到达接收方,接收方需要发出一个确认应答,表示已经收到该数据段,并且确认序号会说明了它下一次需要接收的数据序列号。如果发送方迟迟未收到确认应答,那么可能是发送的数据丢失,也可能是确认应答丢失,这时发送方在等待一定时间后会进行重传。这个时间一般是2*RTT(报文段往返时间)+一个偏差值
-
校验和
TCP将保持它首部和数据的检验和。这是一个端到端的检验和,目的是检测数据在传输过程中的任何变化。如果收到段的检验和有差错,TCP将丢弃这个报文段和不确认收到此报文段
-
拥塞控制
人如果把拥塞窗口cwnd定的很大,那么发送端不停的发送数据,有可能导致网络拥塞。一般会有慢启动和拥塞避免和快速重传策略。
慢启动:定义拥塞窗口,一开始设为1,之后每次收到一个确认应答(经过一个RTT),窗口大小乘2.
拥塞避免:设置慢启动阈值,一般开始都为65536。拥塞避免指当前拥塞窗口大小达到这个阈值,拥塞窗口的值不再指数上升,而是加法增加,(每次确认应答/每个RTT,拥塞窗口+1),以避免拥塞。
报文超时处理:包括快速重传和快速恢复两种。报文超时重传看作一次拥塞,一旦发生超时重传,窗口阈值变为原来大小的一半,并且将窗口大小设为初始值1,然后进入慢启动过程。
快速重传:
在 TCP 传输过程中,如果发生了丢包,接收端就会发送之前重复 ACK,比如 第 5 个包丢了,6、7 达到,然后接收端会为 5,6,7 都发送第四个包的 ACK,这个时候发送端受到了 3 个重复的 ACK,意识到丢包了,就会马上进行重传,而不用等到 RTO (超时重传的时间)
*选择性重传:报文首部可选性中加入 SACK 属性,通过 left edge 和 right edge 标志那些包到了,然后重传没到的包
快速恢复:
当发送方连续收到了三次重复ACK时,就认为当前网络处于拥塞状态,就会进入快速恢复:
- 将拥塞阈值降低为拥塞窗口的一半;
- 将拥塞窗口的大小变为拥塞阈值;
- 接着拥塞窗口再线性增加,以适应网络环境;
可靠传输的工作原理
TCP发送的报文段是交给 IP 层传送的,但IP层只能提供尽最大努力服务,那么TCP 下面的网络提供的是不可靠的传输,因此,TCP必须采用适当的措施才能使两个运输层之间的通信变得可靠。
理想的传输条件
- 传输信道不产生差错
- 不管发送方以多快的速度发送数据,接收方总是来得及处理收到的数据
使用可靠传输协议达到上述条件,使不可靠的传输信道变为可靠传输信道
基于不可靠信道实现可靠数据传输采取的措施:
- 差错检测:利用编码实现数据包传输过程中的比特差错检测
- 确认:接收方向发送方反馈接收状态
- 重传:发送方重新发送接收方没有正确接收的数据
- 序号:确保数据按序提交
- 计时器:解决数据丢失问题;
1️⃣停止等待协议:是最简单的可靠传输协议,但是该协议对信道的利用率不高。
2️⃣连续ARQ(Automatic Repeat reQuest:自动重传请求)协议:滑动窗口+累计确认,大幅提高了信道的利用率。
TCP协议的可靠传输实现
基于连续ARQ协议,但在某些情况下,重传的效率并不高,会重复传输部分已经成功接收的字节。
TCP协议的流量控制
流量控制:让发送方发送速率不要太快,TCP协议使用滑动窗口实现流量控制。
TCP协议的拥塞控制
拥塞控制与流量控制的区别:流量控制考虑点对点的通信量的控制,而拥塞控制考虑整个网络,是全局性的考虑。拥塞控制的方法:慢启动算法+拥塞避免算法。
慢开始和拥塞避免:
- 【慢开始】拥塞窗口从1指数增长;
- 到达阈值时进入【拥塞避免】,变成+1增长;
- 【超时】,阈值变为当前cwnd的一半(不能<2);
- 再从【慢开始】,拥塞窗口从1指数增长。
快重传和快恢复:
- 发送方连续收到3个冗余ACK,执行【快重传】,不必等计时器超时;
- 执行【快恢复】,阈值变为当前cwnd的一半(不能<2),并从此新的ssthresh点进入【拥塞避免】。
TCP与UDP区别
- TCP是面向连接的协议,发送数据前要先建立连接,TCP提供可靠的服务,也就是说,通过TCP连接传输的数据不会丢失,没有重复,并且按顺序到达;
- UDP是无连接的协议,发送数据前不需要建立连接,是没有可靠性;
- TCP通信类似于于要打个电话,接通了,确认身份后,才开始进行通行;
- UDP通信类似于学校广播,靠着广播播报直接进行通信。
- TCP只支持点对点通信,UDP支持一对一、一对多、多对一、多对多;
- TCP是面向字节流的,UDP是面向报文的; 面向字节流是指发送数据时以字节为单位,一个数据包可以拆分成若干组进行发送,而UDP一个报文只能一次发完。
- TCP首部开销(20字节)比UDP首部开销(8字节)要大
- UDP 的主机不需要维持复杂的连接状态表
TCP和UDP各自适用的场景
两者都是传输层协议。
- TCP是可靠的有连接的(收发双方必须建立连接才能传输,三次握手),而UDP是面向无连接的;
- TCP是点对点传输,而UDP可以一对多,多对多,多对一的交互通信;
- 可靠性:TCP是无差错,不丢失,不重复,按序到达;UDP是尽最大努力交付;
- 拥塞控制,流量控制:TCP有拥塞控制和流量控制机制;UDP没有。
- 首部开销:
-
- TCP为20个字节
- UDP为8个字节(源端口,目的端口,数据长度,校验和)
- 适用场景: tcp适用于可靠性高的场景,而udp适用于实时性强的场景(即时通信,视频聊天)
对某些实时性要求比较高的情况使用UDP,比如游戏,媒体通信,实时直播,即使出现传输错误也可以容忍;其它大部分情况下,HTTP都是用TCP,因为要求传输的内容可靠,不出现丢失的情况
资料来源
\