关于黏包

2023-12-01 23:58
文章标签 黏包

本文主要是介绍关于黏包,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

UDP丢包是因为数据包在传送过程中丢失了 而 TCP是基于流式的发送 并且存在丢包重发机制 TCP是可靠连接而 UDP是不可靠的这个我就不多说了
关于 TCP的粘包 正是由于TCP是流式传送的 也就是连接建立后可以一直不停的发送 并没有明确的边界定义 而你用 UDP发送的时候 是可以按照一个一个数据包去发送的 一个数据包就是一个明确的边界
而TCP并没有数据包的概念 是完全流式的 他会开辟一个缓冲区 发送端往其中写入数据 每过一段时间就发送出去 然后接收端接收到这些数据 但是并不是说我发送了一次数据就肯定发送出去了 数据会在缓冲区中 有可能后续发送的数据和之前发送的数据同时存在缓冲区中随后一起发送 这就是粘包的一种形式 接收端也有产生粘包的情况 如果应用程序没有及时处理缓冲区中的数据 那么后续到达的数据会继续存放到缓冲区中 也就是2次接收的数据同时存在缓冲区中 下次取缓冲区的时候就会取出2次粘包后的数据 这是粘包的另外一种形式 还有其他许多形式 比如填充缓冲区到一半缓冲区满了直接发送了 但是其实那个包还没填充完全 这个就是不完整的粘包了 剩余数据会在下次发送的时候补上

关于解决方法 如果你是连续的整个数据流 比如发送文件 那么完全不考虑粘包也无所谓 因为可以建立连接后发送 发送完毕后断开连接 整个数据流就是整个一个文件 无论数据从那里切开都无所谓 整个拼接后依旧是整个一个文件的数据
如果你发送的数据是多次通信 比如把一个目录下所有的文件名都发送过去 那么就不能当作一个整体发送了 必须对他们划分边界 有一个很简单的处理方法 就是采用"数据长度+实际数据"的格式来发送数据 这个"数据长度"的格式是固定宽度的 比如4字节 可以表示0~4GB的宽度了 足够用了 这个宽度说明了后续实际数据的宽度 这样你就可以把粘包后的数据按照正确的宽度取出来了
每次都是取出4字节 随后按照正确的宽度取出后续部分的就OK了
如果你的所有数据都是固定宽度的 比如不停的发送温度数据 每个都是1字节 那么宽度已知了 每次你都取出一个1字节就OK了 所以就不用发送宽度数据了
当然你也可以按照建立连接断开连接来划分边界 每次发送数据都打开关闭一次连接 不过对于频繁的小数据量是不可取的做法 因为开销太大 建立连接和关闭连接也是需要耗费网络流量的
总而言之 粘包的情况是无法绝对避免的 因为网络环境是很复杂的 依赖发送和接收缓冲区的控制是不能保证 100%的 只要在发送的数据中说明数据的宽度随后在接收部分按照这个宽度拆开就OK了 宽度全都是统一的已知宽度的情况下拆开更加容易 连在发送端填入宽度数据都可以省去了

这篇关于关于黏包的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/443180

相关文章

Netty游戏服务器之四protobuf编解码和黏包处理

我们还没讲客户端怎么向服务器发送消息,服务器怎么接受消息。   在讲这个之前我们先要了解一点就是tcp底层存在粘包和拆包的机制,所以我们在进行消息传递的时候要考虑这个问题。   看了netty权威这里处理的办法: 我决定netty采用自带的半包解码器LengthDecoder()的类处理粘包的问题,客户端我是用这里的第三种思路。 消息的前四个字节是整个消息的长度,客户端接收到消息的时候就将前4

从零开始学习Netty - 学习笔记 -Netty入门【半包,黏包】

Netty进阶 1.黏包半包 1.1.黏包 服务端代码 public class HelloWorldServer {private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());public static void main(String[] args)

socket 编程(变态剖析)+超多案例 : 模拟Xshell执行远程命令, 模拟QQ聊天, 时间格式化服务器, 高效解决黏包方法

引入 首先在前面储备知识中了解了OSI七层模型的工作原理以及TCP与UDP的区别之后, 下面的内容就非常容易理解了 一.客户端 / 浏览器与服务端架构 在了解 socket 之前我们先要知道什么是 C/S, 什么是 B/C? 我们知道软件之间的通信是基于计算机的三层结构 (应用程序、操作系统、计算机硬件) 来进行的, 而 C/S 和 B/S 是互联网软件通信的两种模式 C/S 指

socket,socketserver,tcp黏包问题,网络编程

1,socket的使用 基于TCP的socket的使用TCP是有链接,面向流的,客户端和服务端一旦连接,不在断开的时候是不会断的简单使用 1 #!/usr/bin/env python 2 # -*- coding: utf-8 -*- 3 # @time : 2019/6/13 19:36 4 # @Author : aolishuai 5 # @File

tcp的拆包,黏包解决方案

在进行Java NIO学习时,发现,如果客户端连续不断的向服务端发送数据包时,服务端接收的数据会出现两个数据包粘在一起的情况,这就是TCP协议中经常会遇到的粘包以及拆包的问题。 我们都知道TCP属于传输层的协议,传输层除了有TCP协议外还有UDP协议。那么UDP是否会发生粘包或拆包的现象呢?答案是不会。UDP是基于报文发送的,从UDP的帧结构可以看出,在UDP首部采用了16bit来指示UDP数据

【TCP协议】(3)---TCP粘包黏包

【TCP协议】(3)---TCP粘包黏包 有关TCP协议之前写过两篇博客:       1、【TCP协议】(1)---TCP协议详解       2、【TCP协议】(2)---TCP三次握手和四次挥手 一、TCP粘包、拆包图解 假设客户端分别发送了两个数据包D1和D2给服务端,由于服务端一次读取到字节数是不确定的,故可能存在以下四种情况:       1)服务端分两次读取到了两个独