Server Message - 粘包、分包(六)

粘包和分包是利用 Socket 在TCP 协议下内部的优化机制
1、什么是粘包?
包:数据,每次在 客户端 调用的 Send()方法,里边传输的数据。
当我们发送数据比较频繁,但是数据量又很小的时候,不会立刻发送到服务器端,会和其他的数据进行一个结合,原来的时候调用 Send()方法是需要将 数据发送出去的,如果说发送消息比较频繁的话,每秒都要发送几十次消息的话,而且每个消息又很小,这个时候如果频繁的发送是很耗费性能的,所以就会把包进行一个打包,粘包的话通俗的理解就是包与包粘在了一起。
粘包问题的本质就是数据读取边界错误所致
eg:在开发网络游戏的时候,会同步一些位置信息,攻击的信息。各种信息进行同步的时候,这种情况下会出现粘包问题
虽然会出现粘包的情况,但是到达的先后顺序不会发生改变

补充:对于UDP,不会使用块的合并优化算法,这样,实际上目前认为,是由于UDP支持的是一对多的模式,所以接收端的skbuff(套接字缓冲区)采用了链式结构来记录每一个到达的UDP包,在每个UDP包中就有了消息头(消息来源地址,端口等信息),这样,对于接收端来说,就容易进行区分处理了。所以UDP不会出现粘包问题。
在这里插入图片描述
在这里插入图片描述
这里最简单的演示情况就是,直接在客户端这边,向服务器发送一个数字信息,从而达到一个演示,so 我这里直接发送 1-100 的数字。那么在客户端这边就是:
在这里插入图片描述
那么最后出现的问题也就是:
在这里插入图片描述
在这里插入图片描述
3个字节代表一个汉字、上图中的???代表了一个汉字,把第一个?放到了上一个包里面,剩下的两个??放到了下一个包里面

2、什么是分包?
当发送的消息特别长,特别大的时候,上千上万的字的时候,就会去分开发送,对于数据来说,如果把大数据包一次性进行发送的话,中间如果发送失败了的哈,就会很占用时间了,而且大包比较占用网速,包发送失败的时候重新发送比较占用时间,如果说将一个大包 分开进行发送,一个大包分为十个 小包进行发送的话,每个小包只有几百个字节,按照小包进行发送。不用把整个包整体发送,分包发送的一般是在 我们的数据很大很多的时候,有可能会进行分开发送。
那么针对上面的粘包问题,这里直接就是 处理粘包的问题,直接上代码了:
(1)分包的问题导致的第一个原因?
在接收的时候定义了一个 Size,前面定义的一个值是 1024,这里我将它 扩大 10 倍,也就是 10240,可以看到的是 只是从客户端收到了一个消息。换句话也就是说 在 异步的情况下,数组的 Size 给的足够大的时候,就不会产生分包了。
(2)一般来说 不需要 将 Size 设置的特别大,因为我们 只需要保证每一条数据大小,在做网络游戏同步的时候,每个存储的最大为 几百个 字符。
在网络游戏开发中,我们需要经常考虑的是 粘包问题,而分包问题只是说上传的文件很大的时候才会去进行考虑。因为发送的一些消息都比较的小

3、如何处理粘包、分包??
在这里插入图片描述
解决粘包和分包的方案:每次都发送数据的时候都是一个 byte[] 数组,这个数组是有一个大小的,那么在这个数据的前面给他加上一个 数据,代表着我们数据的长度,吧数据的长度放在第一个位置,这个地方的长度代表了数据一共有多少个字节,比如说有 40 个字节,每次读取的时候先读取到数据的长度,然后向后 进行读取,假如说接收到的消息不够 40 的话,只有 15个字节的时候,说明数据不够,不够的话就不处理,继续进行一个接收,如果再次接收到了以后,就再进行一个判断,后面的数据是否满足 40 个字节,如果满足了说明数据大小够了,如果说数据大小够了,我们才会开始处理消息。
这样的话根据数据长度,取得消息。消息一条一条的处理。
由于我们的消息长度是不固定的,所以我们前面存储的长度,必须得为固定。
如果说它是不固定的,那么就没有办法进行处理了,因为有的时候是 3 个有的时候是4 个,所以根本不知道消息使用的数据长度占用了多少字节,因为我们的消息肯定是整形的,那么如何将一个整形存储到一个字节中呢?
使用一个 int 32 类型的变量进行接收,因为它是占有 4 个字节的
一个字节是 8 位
在这里插入图片描述
用前面恒定4个长度去存储数据长度,每次接收到数据的时候先存储前 4 个字节,然后把前 4 个字节读取出来,然后转化成一个长度,再按照这个长度往后面读取,从而解决 粘包和 分包的解决。

那么如何将一个 int 32 整形转换为 4 个字节的数组呢?

欢迎加入 游戏外包群:
1067304356

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值