1.UDP是无连接,TCP是有连接
- 发送数据之前需要进行连接
2.UDP不保证可靠传输和有序传输,TCP则保证
- UDP中当sendto大于64K-8,则需要在应用层分包;多次发送,并在接收端手动拼装,因为不保证可靠传输和有序传输,还应该在应用层进行包序管理;
- TCP协议字段中的序号字段保证了数据的有序传输,以及各种机制保证了可靠传输
3.UDP是面向数据报,TCP是面向字节流
- UDP中不能够灵活的控制读写数据的次数和数量
应用层交给UDP多长的报文,UDP原样发送,既不会拆分,也不会合并;(UDP数据只能整条交付); - TCP中发送端执行的写操作次数和接收端执行的读操作次数之间没有任何数量关系,应用程序对数据的发送和接收是没有边界限制的
传输灵活,按照字节传输/接收数据,可以堆积起来,一次性接收数据(但是这样有时会存在粘包问题),也可以一个一个字节去接收;
面向字节流:
创建一个TCP的socket, 同时在内核中创建一个发送缓冲区 和一个接收缓冲区;
- 调用write时, 数据会先写入发送缓冲区中;
- 如果发送的字节数太长, 会被拆分成多个TCP的数据包发出;
- 如果发送的字节数太短, 就会先在缓冲区里等待, 等到缓冲区长度差不多了, 或者其他合适的时机发送出去;
- 接收数据的时候, 数据也是从网卡驱动程序到达内核的接收缓冲区;
- 然后应用程序可以调用read从接收缓冲区拿数据;
- 另一方面, TCP的一个连接, 既有发送缓冲区, 也有接收缓冲区, 那么对于这一个连接, 既可以读数据, 也可以写数据. 这个概念叫做 全双工
由于缓冲区的存在, TCP程序的读和写不需要一一匹配,
例如: - 写100个字节数据时, 可以调用一次write写100个字节, 也可以调用100次write, 每次写一个字节;
- 读100个字节数据时, 也完全不需要考虑写的时候是怎么写的, 既可以一次read 100个字节, 也可以一次
read一个字节, 重复100次;
作用:提高传输性能,并且使数据之间的交付比较灵活
4.TCP连接只能是点到点,一对一,而UDP支持一对一,一对多,多对一和多对多的交互通信
- 指的是连接对象的数量上
5.TCP存在粘包问题,UDP不存在
粘包问题:"包"指的是在应用层的数据包(数据之间没有间隔)
本质原因:TCP再传输层对数据格式边界不敏感
- 在TCP协议头中,没有UDP一样的报文长度,但是有序号这个字段
- 站在传输层角度,TCP是一个一个报文过来的,按照序号排好序放在缓冲区中
- 站在应用层角度,看到的只是一串连续的字节数据
- 那么应用程序看到这一连串的数据,不知道从哪个部分开始到那个部分
如何避免粘包问题???
简单来说就是,明确两个包之间的边界
- 用特殊字符进行间隔
- 数据定长
- 不定长的数据在应用头中,声明数据的长度
UDP为啥不存在粘包问题???
- 对于UDP, 如果还没有上层交付数据, UDP的报文长度仍然在. 同时, UDP是一个一个把数据交付给应用层. 就有很明确的数据边界.
- 站在应用层的角度, 使用UDP的时候, 要么收到完整的UDP报文, 要么不收. 不会出现"半个"的情况.
6.UDP传输效率高,TCP传输效率低
- UDP讲究实时性,例如视频传输等,TCP讲究可靠性,例如文件传输等;