TCP和UDP
TCP和UDP区别
TCP | UDP | |
---|---|---|
连接 | 面向连接的可靠性传输 | 无连接不可靠 |
传输模式 | 流模式 | 数据报模式 |
面向字节流 | 面向报文 | |
只能是一对一 | 一对一或一对多 | |
首部 | 首部较大,有20字节 | 首部只有8字节 |
应用场景 | 用于需要可靠传输的情况 | 用于高速传输和对实时性有较高要求的通信(视频、音频等多媒体通信)或广播通信 |
资源消耗 | 要求更多系统资源 | 较少 |
可靠传输 | 可靠(保证数据正确、不重传、有序) | 不可靠(尽最大努力交付,但不保证可靠交付;可能丢包、不保证顺序、无序) |
纠错能力 | 是 | 否 |
流量控制 | 是 | 否 |
拥塞控制 | 是 | 否 |
重传机制 | 是 | 否 |
速度 | 较慢 | 快速 |
传输成本 | 更高一点 | 较低 |
-
TCP 属于通过增大延迟和传输成本来保证质量的通信方式
-
UDP 是通过牺牲质量来保证时延和成本的通信方式
TCP和UDP使用场景
-
TCP:可靠传输数据,不对速度有太高要求。比如网页,丢失一个数据包,页面可能就无法正确展示了;还有电子邮件、SSH软件、多数在线游戏等等,我们必须不惜一切代价接收每个发送的数据包。
-
UDP:立即传输数据,允许传输时丢失一些信息。效率高、速度快、占资源少、但是其传输机制为不可靠传送,必须依靠辅助的算法来完成传输控制。主要是流媒体应用程序,例如互联网广播、互联网电视等,此类场景用户可以忍受偶尔的断断续续,因此丢失一个或多个数据包,没有什么影响
为什么UDP不可靠
-
UDP的下层是网络层/IP层。IP层的主要任务就是按照源IP地址向目标IP地址发送数据报。而UDP协议不管这个发送能否成功,它直接将这个发送的结果抛给上层传输层处理了。(只有发送过程,没有确认的过程,不管是否发送成功只要发了就完事了。)
-
UDP只有一个socket接受缓冲区,没有socket发送缓冲区,即只要有数据就发不管接收方是否可以正确接受。而在对方的socket接受缓冲区满了之后,新来的数据报无法进入到socket接受缓冲区,此数据报就会被丢弃,udp是没有流量控制的,所以UDP的数据传输是不可靠的。
- 补充:Socket缓冲区:应用程序通过调用send, read方法向网络上发送应用数据,该过程中由于应用程序调用send/write的速度同网络介质发送数据的速度存在差异,所以,应用通过socket发往网络上的的数据会先被缓存,即socket发送缓冲区,等待网络空闲时再发送出去。同样,socket从网络上接受到的数据,也会被缓存,即socket接受缓冲区,等待应用程序把数据从中读出。其中,应用程序调用send发送数据,是将数据拷贝到socket的内核发送缓冲区中,然后send便会返回,即send返回后,数据并不一定发送到目的地去了,send仅仅是把数据拷贝到socket的内核发送缓冲区。
-
丢包和无序(UDP丢包可能性有:传输过程中丢包、接收设备缓存不足)
-
不保证消息交付:不确认,不重传,无超时
-
不保证交付顺序:不设置包序号,不重排,不会发生队首阻塞
-
不跟踪连接状态: 不必建立连接或重启状态机
-
不需要拥塞控制: 不内置客户端或网络反馈机制
-
UDP仅提供了校验和机制来保障一个报文是否完整,若校验失败则直接丢弃报文。
为什么TCP可靠
-
可以保证数据传输的有序性:TCP只有收到正确连续顺序的数据才会提交到上层应用层。
-
保证数据传输的准确性:数据丢失:数据丢失的话会触发重传机制、数据错误:TCP会对消息本身做校验计算
- TCP是有链接的协议,在连接的握手状态就会有一个起始编号,这个编号会随着后续消息的发送而不断增加,且消息是基于字节流的,每个字节在发送之处就会被编号,当某一段消息/多个连续消息由于其他原因丢失,就会触发重传消息机制,发送端会根据超时消息,将数据重新发送,或者根据接受端给出的消息编号选择性的发送消息,这样就保证了消息的无误性,不会乱序不会丢失。TCP还会对消息本身做校验计算,这是为了保证消息序号不变的同时,消息内容发生错误的情况。
-
补充:TCP的重传机制:超时重传、快速重传/选择性确认。(TCP一旦出现超时重传,需要重新开始执行慢启动算法;当触发快速重传后,需要直接执行快速恢复算法。!?)
其实也相当于TCP原理的问题了,可以看下面的 TCP原理 部分,结合来看。
如何让不可靠的UDP变可靠
= 说一下使用UDP实现可靠数据传输的大体设计思路? = 如何设计基于udp的可靠传输?
-
重传。这也就是我们通常意义上的 RUDP 行为。RUDP的重传通过接收端ACK的丢包信息反馈来进行数据重传,发送端会根据场景来设计自己的重传方式,常见有3类:超时重传、请求重传、FEC选择重传。
-
但是通过重传通过重传来保证质量会导致2个问题:延时、带宽消耗。带宽消耗如果控制不好可能导致网络风暴,所以需要做拥塞控制。(但是UDP里面是没有拥塞控制这个功能的,这个怎么解决!?)
-
针对于UDP丢包问题:双方增加握手(相当于在UDP协议里面加上了TCP的实现方法.)、实现确认和重传
-
总结来说:在应用层做一个模仿TCP传输的机制,如:添加seq/ack机制、添加发送和接收缓冲区、添加超时重传机制。目前有一些开源程序,如RUDP、RTP、UDT。
详情可以参考:https://zhuanlan.zhihu.com/p/163569041
一些游戏为什么用UDP不用TCP
-
TCP在一些苛刻的网络条件下,要么不能提供正常的通信质量保证,因为传输速度慢,要么成本过高。
-
在 UDP 上做可靠保证,原因就是在保证通信的时延和质量的条件下尽量降低成本。
TCP流量控制和拥塞控制
见我的另一篇博客:https://www.cnblogs.com/OFSHK/p/14579947.html
TCP工作原理
TCP数据的传输过程 = TCP如何实现可靠的数据传输 = TCP工作原理
可靠的数据传输 = 保证数据无差错、无丢失、按序和无重复的交付
-
数据编号和确认
-
TCP 给发送的每一个包进行编号,接收方对数据包进行排序,把有序数据传送给应用层。
-
校验和/确认: TCP 将保持它首部和数据的检验和。这是一个端到端的检验和,目的是检测数据在传输过程中的任何变化。如果收到段的检验和有差错,TCP 将丢弃这个报文段和不确认收到此报文段。TCP 的接收端会丢弃重复的数据。
-
-
滑动窗口机制
-
超时重传
-
快速重传
-
选择确认
-
拥塞控制机制:慢启动+拥塞避免;快速重传+快速恢复
-
流量控制
-
ARQ协议