正如我们所知道的,TCP是面向连接,可靠的,字节流服务;而UDP是无连接、不可靠的,数据报服务。
接下来进行简单的解释:
1、TCP是面向连接的,在进行交互之前必须建立好连接,这如我们打电话一样,在通话之前,必须要进行拨号来建立连接(通过三次握手建立连接和四次挥手来释放连接);而UDP是无连接的,在进行信息交互之前不需要建立连接。所以说,UDP更加的高效。
2、TCP是提供可靠的服务,TCP协议通过一系列的机制,使通过连接传输的数据是,无差错,不丢失的,不重复的,按序到达。即发送的数据是什么样的,接受到的数据就是什么样的。UDP则是尽最大努力进行交付,但不保证可靠性,即发送方只管发送数据,而不管数据是否能够准确到达,且不能保证到达数据是否有差错。
3、TCP是进行流数据传输,而UDP是数据报服务,用在linux上实际编程中的使用来解释这两种数据服务的区别:
字节流:
①send函数发送的次数与recv函数接受的次数没有必然的关系。
②数据传输时,具体数据分为几个TCP报文段传送和send函数调用的次数是没有关系的。
③应用程序对数据的发送和接收是没有界限的;
因为,TCP在发送和接受的时候都有缓冲区,send函数只是将一个个数据拷贝到TCP的发送缓冲区中,而这些数据拼接在一起,可以看做是一条河流,具体这条河流的那一段被封装成了一条TCP报文段和send函数没有一点关系,然后接受方将TCP报文段上的数据也拷贝到自己的接受缓冲区中,调用一次recv函数就能够按recv函数一次能读取数据的长度进行读取数据,如果一次没有读完,其他的数据不会丢失,保存在缓冲区中,下次recv函数会接着读取。(这样就会出现粘包问题:recv函数一次未读取完,下一次recv函数将接着上次读取的位置读取)
数据报:
①数据的发送和接收的次数是相等的,一次sendto函数对应着一个UDP报文段。
②UDP协议传输的数据是一段一段的,每一段就是一个UDP报文段。
③recvfrom函数而言,如果一次读取不能将所有的数据读取完毕的话,其余的数据将会被丢弃。
一个sendto函数,就对应着一个UDP报文段,UDP协议没有缓冲区,数据就是一个个的报文段来传输的,所以发送一个报文段(调用一次sendto函数),接收也只能接受一个报文段(调用一次recvfrom函数),由于没有缓冲区,一次没有读取完的数据没有地方保存,所以就被丢弃了。这也是UDP协议的不可靠性的一种体现。
字节流服务和数据报服务的区别:
TCP的报头:
由图可知:TCP的报头最少有20字节,最多有60字节(保留部分最多40字节),包含有源端口,目标端口,序列号,确认号等复杂的控制信息,来确保TCP的可靠性。
而UDP的报头如下:
因为UDP是无连接,不可靠的,所以不需要太多的控制信息,所以相对于TCP的报头来说,就比较简单。但依旧还有防止出错的校验和段。