C# socket粘包断包处理

本文详细介绍了在C#中处理Socket通信时遇到的粘包和断包问题,通过构建消息头和解析消息长度来确保数据的完整接收。主要内容包括构建消息头的步骤,如何尝试获取完整消息,以及多余的字节如何处理。文章提供了完整的代码示例,帮助读者理解和解决此类问题。
摘要由CSDN通过智能技术生成

目录

 

概述

构建消息头

解析消息

完整代码


概述

socket接收消息的时候经常会出现粘包和断包的问题。

比如:

发送的时候有1000个字节,但是一次接收只有600个字节。即一条完整的消息在接收的时候断开了

两次发送分别发送了1000个字节,但是一次接收到了1500个字节,第二次才收到另外500个字节。即一条完整的消息在一次接收的时候还额外收到了其他消息的部分数据,甚至一次多条数据。

这里尝试的解决办法是对每个消息拆分为几个部分,其中最重要的是消息头header和消息长度len。

当我们收到消息的时候首先判定header当前字节是否为一条消息的开始,然后利用len字段可以知道当前收到的数据是否完整。

主要的处理有三块:

  1. 构建消息头
  2. 尝试获取一条完整的消息
  3. 若某次获取到完整的消息后还有多余的字节则缓存起来继续递归解析消息

构建消息头

其中传入的参数为,tcp接收到的二进制数组。

首先我们让缓存的字节长度超过一个消息头的长度(即header+len的长度,也可以自己额外定义一些其他消息头的内容)

判定消息头的第一个字节为我们字节约定好的header,然后将后面的N个字节解析成int即为单条消息的长度了。

如果第一位不是我们约定好的则直接将整个消息丢掉。

确定好header位,确定好消息长度消息头就构建好了。

// 构建消息头
        private bool BuildMessageHead(byte[] mArryRecData)
        {
            mArryBuffer = CommonTool.CombineArry(mArryBuffer, mArryRecData);

            // 未获取到获取消息长度则先获取消息长度
            if (intMessageLen == -1)
            {
                // 头部长度足够
                if (mArryBuffer.Length >= TcpData.TCP_HEADER_LEN)
                {
                    // 判定标志位并设置消息长度
                    if (mArryBuffer[0].Equals(TcpData.TCP_HEAD_MARK))
                    {
                        SetMessageLen(mArryBuffer);
                        return true;
                    }
               
  • 0
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值