分享

根据首尾字节的tcp分包断包算法

 心不留意外尘 2016-09-03

根据首尾字节的tcp分包断包算法


http://www.cnblogs.com/songjingsong/p/3837118.html?utm_source=tuicool&utm_medium=referral


 posted on 2014-07-11 

这个算是我的一点小总结吧,放出来分享给大家,原来在网上找这种算法都找了N久没找到,自己写也是走了许多弯路,就放出来遛一遛吧


 大家将就这个看看, 这是其中的一个主要的方法,其余的我就不放出来了,其中的IndexTag和endTag分别是首尾字节




public List<Gnss808RequesInfo> Filter(ref byte[] message)

        {

            var list = new List<Gnss808RequesInfo>();

            //是否退出循环

            var isBreak = false;

            while (true)

            {

                //如果缓冲区字节数组为空或者长度为小于1

                if (isBreak || message == null)

                {

                    break;

                }

                //首指针

                var flag = -1;

                for (var i = 0; i < message.Length; i++)

                {

                    //判断首标识是否正确

                    if (i - flag == 1 && message[i] != IndexTag)

                    {

                        message = null;

                        LogHelper.Instance.Add("分包不正确,丢弃字节");

                        break;

                    }

                    //如果是结束字符(且不为首字节,区分如果首标识和尾标识相同的情况)

                    if (i - flag != 1 && message[i] == EndTag)

                    {

                        var data = new byte[i - flag];

                        Array.Copy(message, flag + 1, data, 0, i - flag);

                        //这个地方其实已经收到一个完整的数据包了

                        //下面的重载的方法生成规定的数据格式的接口

                        var request = Filter(data);

                        if (request != null)

                        {

                            list.Add(request);

                        }

                        flag = i;

                    }

                    //该为最后一个字节

                    if (i == message.Length - 1)

                    {

                        if (flag == i)

                        {

                            message = null;

                        }

                        else

                        {

                            //未接收完整的数据包

                            var data = new byte[message.Length - flag - 1];

                            Array.Copy(message, flag + 1, data, 0, data.Length);

                            message = data;

                           // LogHelper.Instance.Add(string.Format("未知:{0}", CommonFunction.GetBcdCodeString(message, 0, message.Length)));

                        }

                        //退出循环

                        isBreak = true;

                        break;

                    }

                }

            }

            return list;

        }


 


评论

 

 李占卫   | 2014-07-11 10:35


1:没看到如果首字节正好是IndexTag的逻辑。

2:分包还有个算法就是长度加内容


public byte[] GetData(int ml)

{

if (ByteList.Count < ml)

return null;

int res = 0;

for (int i = 0; i < ml; i++)

{

int temp = ((int)ByteList[Current + i]) & 0xff;

temp <<= i * 8;

res = temp + res;

}

if (res <= 0)

{

Reset();

ByteList.Clear();

return null;

}

if (res > (ByteList.Count - Current))

return null;

byte[] data = new byte[res];

ByteList.CopyTo(Current, data, 0, data.Length);

Current += res;

if (Current == ByteList.Count)

{

Reset();

ByteList.Clear();

}

return data;

}






#4楼[楼主]    

 Idiotworker   | 2014-07-11 10:37

@ 李占卫

有的,

 

//判断首标识是否正确

                   if (i - flag == 1 && message[i] != IndexTag)

                   {

                       message = null;

                       LogHelper.Instance.Add("分包不正确,丢弃字节");

                       break;

                   }




#5楼    

 lianghugg   | 2014-07-11 10:44

我教你一个好方法吧,把字节码转为Hex字符串,直接Split字符串就可以了~方便快捷o !

 

#6楼[楼主]    

 Idiotworker   | 2014-07-11 10:47

@ LiangHu

我第一次接触网关看到别人就是这么写的,先把字节数组转换成字符串,解包后再转成字节数组。。

 

#7楼    

 阿超-   | 2014-07-11 14:25

 

测试一下能用???

 

#8楼[楼主]    

 Idiotworker   | 2014-07-11 14:25

@ 阿超-

当然是可以用的啊,我很多后台都是用这个的好吧


    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约