传输层--TCP和UDP的对比

TCP和UDP协议是传输层非常重要的两个协议,这两个协议在数据传输中起着非常重要的作用,前面两篇文章讲解了这两个协议各自的特点,本文来讲解一下这两个协议有什么区别。

从各自的特点来看


1.TCP是面向连接的,而UDP是无连接的;

TCP发送数据前先要建立连接,而UDP发送数据前不需要建立连接。

2.TCP保证可靠性,UDP不保证可靠性;

TCP具有很多的可靠性保证机制(TCP的连接管理、超时重传、序号和确认序号、流量控制和拥塞控制都能保证TCP数据包能够无差错、不丢失、按序到达),但是UDP没有这些可靠性保证机制,因此UDP就无法保证可靠性。

3.TCP面向字节流,UDP面向数据报;

TCP接收和发送数据就像流水一样,可以一次接收多个,或者一次接收少半部分但是可以接收多次;但是UDP发送多少就要接收多少,如果接收的数据少于发送的数据,那么少的那部分数据永远也接收不到了。

4.每一条TCP连接只能用于点点之间一对一进行,而UDP支持一对一、一对多、多对多的交互通信;
5.TCP不仅有接收缓冲区还有发送缓冲区,而UDP只有接收缓冲区。

因为TCP为了能够超时重传时需要重传的数据还在,那么TCP就需要把以前发送的数据进行缓存起来,方便以后重发,因此就需要发送缓冲区;但是UDP不保证可靠性,没有超时重传,那么UDP就不用保存他以前发送的数据,因此UDP就没有发送缓冲区。

从各自报头来看


1.TCP的报头默认占20字节,而UDP的报头占8字节,因此TCP比UDP要更耗资源;
2.UDP的报头只有4个内容:源端口号、目的端口号、16位校验和以及16位总长度;
而TCP里面的报头里包含与UDP相同的源端口号、目的端口号及16位校验和,还有为了保证可靠性比UDP多的序号、确认序号、窗口大小还包括特别重要的6位标志位(URG、ACK、PSH、RST、SYN、FIN),TCP的报头多的这些内容为TCP保证可靠性提供了重要的依据。
3.UDP的报头里面包含一个16位总长度,使得UDP报文长度可以得到确定;但是TCP的报头里面只包含4位首部长度,这个只能确定TCP报头总长度但是不能确定TCP报文(包括TCP首部和TCP数据)总长度,因此TCP具有粘包问题。

从各自编程方面


1.采用UDP编程比采用TCP编程要简单很多;
2.对于服务器来说:

两者首先都需要:
(1)调用socket创建一个套接字;
(2)调用bind函数,绑定端口号和IP地址到socket上;
当这两步做完之后UDP就可以与客户端进行数据传输,但是TCP还需要调用listen使得创建的套接字变为被动套接字可以一直监听客户端的到来,接下来调用accept一直阻塞等待客户端的连接,当有客户端连接之后此时accept返回一个新的文件描述符,这个文件描述符用来和客户端进行数据交互,此时客户端与服务器就可以进行数据交互。
(3)因此对于服务器来说,TCP服务器需要调用如下接口:socket、bind、listen、accept、close(关闭文件描述符);对于UDP来说,只用进行socket、bind、close。

3.对于客户端来说:

两者首先都需要:
(1)调用socket函数创建套接字;
(2)此时UDP的客户端就可以向服务器发送数据,但是TCP的客户端还需要调用connect 函数与TCP服务器建立连接,当连接建立成功之后,TCP客户端就可以向TCP服务器发送数据。
(3)因此对于客户端来说,TCP客户端需要调用如下接口:socket、connect、close(关闭文件描述符);对于UDP来说,只用进行socket、close。
(4)注意: UDP是可以调用connect函数的,但是UDP的connect函数和TCP的connect函数调用确是大相径庭的,这里没有三次握手过程。内核只是检查是否存在立即可知的错误(比如目的地址不可达),记录对端的IP和端口号,然后立即返回调用进程。
4.TCP套接字可以采用write/read、recvfrom/sendto来进行数据的的读写,但是UDP套接字不能采用write/read,因为read和write是面向字节流的。

UDP如何保证可靠传输


1.因为TCP的可靠性是由确认机制、重传机制、流量控制和拥塞控制来保证的;
2.由于UDP协议不保证可靠性,如果想要UDP编程保证可靠性那么只能由用户层来实现,按照TCP可靠性保证机制来实现类似的机制就可以达到目的。
3.用户自己指定一系列的机制用来保证可靠性:
(1)可以自己定制一个计时器,当计时器时间到了还没有收到对方发的消息,就要求重传;
(2)用于也可以自己对发送的数据进行编号,将收到的数据按照编号顺序存放,如果缺少就要求重传
(3)引入确认应答,保证数据被对方正确收到;
(4)还可以实现拥塞控制等;

TCP的粘包问题


1.什么是粘包问题?

(1)例如蒸包子时,如果 包子比较大,那么最后包子就会黏在一起,当我们取包子有时就会取出半个或者会取出一个半,这就是粘包问题。因为包子与包子之间没有明确的界限。
(2)黏包,黏的是应用层的数据包;
2.因为TCP是面向字节流的,站在应用层的角度看到的就是一串连续的字符串,并且TCP数据报头里面没有包含数据包大小的相关信息,就导致数据包与数据包之间没有明确的界限,就会导致取数据会取出半个或一个半的情形,就会使得读到的数据出现错误,因此必须要解决TCP的粘包问题。

3.如何避免粘包问题?

(1)只要让数据包与数据包之间有明确的界限,那么就可以解决粘包问题;
(2)数据包之间有明确界面可以从如下三个方面来实现:
①可以采用定长的报文(像UDP一样,明确报文的长度);
②确定长度(例如HTTP协议里面有一个字段叫做Content-Length来表示HTTP协议里有效数据的长度,那么TCP协议里面也可以通过类似的方法来明确有效数据的长度);
③可以采用特殊符号来作为分隔符(像HTTP协议中就是采用空行来进行分隔,那么TCP就可以采用类似于空行之类的特殊符号来分隔);

4.UDP是否具有粘包问题?

UDP不具有粘包问题,因为UDP报头里面包含一个字段是16位的UDP总长度,根据总长度就可以确定每个UDP数据包的大小,读取数据按照大小来读,就没有粘包问题。

总结


UDP和TCP在传输层中起着重要的作用,不能一概而论谁好谁坏;
(1)不能因为UDP不保证可靠性就认为UDP对数据传输没有用途,但是因为UDP效率快,虽然不保证可靠性但是有时候传输的数据不要求完全可靠,因此UDP在视频传输方面可以有着重要的作用,因为丢失几个帧并不导致视频的观看。
(2)也不能因为TCP在保证可靠性的条件下做了很多的限制就认为TCP效率较低,TCP也有很多措施用来提升效率(滑动窗口、延迟应答、快重传、捎带应答)。
(3)因此不能从某一个机制的一些缺点来判定该机制的好坏,不同的机制有着不同的应用场景,选取合适的应用场景就可以发挥各自的优势。

猜你喜欢

转载自blog.csdn.net/xu1105775448/article/details/80944076