如何理解面向字节流和面向报文
今天看TCP和UDP的区别,发现很多文章讲到TCP是面向字节流,UDP是面向报文的,好奇查了查,这里做个总结
-
为什么UDP是面向报文的协议
-
用户通过UDP协议传输时,操作系统不会对消息进行拆分,直接组装头部就交给网络层处理
-
所以每个UDP报文就是一个用户消息的边界,读一个UDP报文就能读取到完整的用户消息
-
操作系统在收到UDP报文后,将其插入到队列中,队列中每一个元素都是一个UDP报文,这样用户调用recvfrom()系统调用读取数据的时候,就会从队列拿出数据,从内核里拷贝给用户缓冲区
-
-
为什么TCP是面向字节流的协议
-
通过TCP协议传输时,消息可能会被操作系统分组成多个TCP报文
-
-
调用send()函数完成数据“发送”以后,并没有真正发送,而是从应用程序拷贝到了操作系统内核协议栈中
-
什么时候真正发送,取决于发送窗口,拥塞窗口以及当前发送缓冲区的大小条件
-
-
顺带话题,如何解决粘包,即直到边界的位置来划分出等效的用户消息
-
固定长度的消息:这种方式灵活性不高,实际很少用
-
特殊字符作为边界,比如HTTP的消息头中,使用回车符和换行符
-
注意的是,这个特殊字符如果出现在了消息内容里,需要对这个字符转义
-
-
-
自定义消息结构
-
可以自定义一个消息结构,head固定大小,head里存储一个字段来说明后面的数据有多大
-