解决粘包半包

using System;
using System.Collections.Generic;
using System.Text;

namespace VoxelServer.Network
{
    class ClientMessageHandler
    {
        const int BUFFER_SIZE = 1024;
        public byte[] buffer = new byte[BUFFER_SIZE];
        public int beginIndex = 0;
        int bodyLen = -1;//记录读出的bodylen。-1即为未读.每次处理完数据体后都要置-1
        public int leftSize
        {
            get
            {
                return BUFFER_SIZE-beginIndex;
            }
        }

        public byte[] incompleteBody;//用来存储之前接收但没接受全的数据体
        public void handleReceive(int dataLen)
        {
            int handledLen=0;//记录已经处理的数据长度。等价于下一步数据从哪开始.处理完数据就要+1
            while (handledLen!=dataLen)
            {
                if (incompleteBody == null)//判断是否存在未接收完的数据体,不存在即先读取数据头(数据体长度int32)
                {
                    if (dataLen-handledLen < 4)//判断长度是否达到int32,不到直接return,继续下一次接收。
                    {
                        beginIndex += dataLen - handledLen;
                        if (handledLen>0)
                        {
                            Array.Copy(buffer,0,buffer, handledLen, dataLen - handledLen);
                        }
                        return;
                    }
                    else
                    {
                        bodyLen = BitConverter.ToInt32(buffer, handledLen);
                        handledLen += 4;
                        if (bodyLen > dataLen - handledLen)//数据体长度大于未处理数据长度,把数据体存入previousData
                        {
                            //存入incompleteBody

                            return;
                        }
                        else
                        {
                            //处理数据体

                            //处理完后
                            handledLen += bodyLen;
                            resetBodyLen();
                        }
                    }
                }
                else
                {
                    int leftBodyLen = bodyLen - incompleteBody.Length;
                    if (leftBodyLen > dataLen)
                    {
                        //存入incompleteBody

                        return;
                    }
                    else
                    {
                        //组合数据体

                        //处理数据体

                        //处理完后
                        handledLen += leftBodyLen;
                        resetBodyLen();
                        incompleteBody = null;
                    }
                }
            }
        }
        private void resetBodyLen()
        {
            bodyLen = -1;
        }
    }
}

© 2021 hanbaoaaa record.浙ICP备20005263号
asdad
联系方式 asdasd
2021-5-8 4:19
sss
回复数 (0) 点击展开
加载更多

新增评论

称呼
联系方式
邮箱(选填)
内容

提交

取消