码迷,mamicode.com
首页 > 其他好文 > 详细

Scut:从PackageReader分析客户端协议规则

时间:2016-08-13 21:02:16      阅读:172      评论:0      收藏:0      [点我收藏+]

标签:

  看第一个解析API:

        private void ParseData(byte[] data)
        {
            var paramBytes = SplitBuffer(data);
            RawParam = _encoding.GetString(paramBytes);

            ParseParamString(RawParam);
        }

 

  再看如何分隔数据包:

        private byte[] SplitBuffer(byte[] data)
        {
            int paramIndex = MathUtils.IndexOf(data, EnterChar);    //以“\r\n\r\n”为分隔符
            byte[] paramBytes;
            if (paramIndex >= 0)     //如果有双换行符
            {
                paramBytes = new byte[paramIndex];
                Buffer.BlockCopy(data, 0, paramBytes, 0, paramBytes.Length);                     //将双换行符之前的数据复制出来
                InputStream = new byte[data.Length - paramIndex - EnterChar.Length];
                Buffer.BlockCopy(data, paramIndex + EnterChar.Length, InputStream, 0, InputStream.Length);   //将剩下的数据复制到 InputStream
            }
            else
            {
                paramBytes = data;
            }
            return paramBytes;
        }

  看 Scut 的官方文档,对此也说的很清楚:第一部分是字符串的格式流(命名为Get Params),第二部分是扩展数据流(可选),支持上传些文件流或图片流等,与第一部分之间需要以两个换行(\r\n\r\n)符分隔。

  重点则是对第一部分的格式分析:

        protected virtual void ParseParamString(string paramString)
        {
            string str = paramString;
            int index = paramString.IndexOf(PrefixParamChar, StringComparison.OrdinalIgnoreCase);    //找到协议前缀的位置
            if (index != -1)
            {
                if (paramString.StartsWith(PrefixRouteChar, StringComparison.OrdinalIgnoreCase))
                {
                    //ex: "route:xxx?d="
                    RouteName = paramString.Substring(PrefixRouteChar.Length, index - PrefixRouteChar.Length);
                }
                str = paramString.Substring(index + PrefixParamChar.Length);      //从协议前缀位置开始截断
                str = HttpUtility.UrlDecode(str) ?? "";

            }
            if (!str.Contains("="))
            {
                TraceLog.ReleaseWriteDebug("Parse request error:{0}", paramString);
                return;
            }

            var nvc = HttpUtility.ParseQueryString(str);   //根据 xx=xx&xx=xx 的规则取出数据
            foreach (var key in nvc.AllKeys)
            {
                if (string.IsNullOrEmpty(key)) continue;
                var val = nvc[key];

                if (PrefixRouteChar.StartsWith(key, StringComparison.OrdinalIgnoreCase))
                {
                    RouteName = val;
                    continue;
                }
                this[key] = val;
            }
        }

  

总结:

1. SplitBuffer 主要是做第一部分与第二部分的分离;

2. 第一部分:可知的规则是 ?d=Key1=Value1&Key2=Value2... 并且要执行一次 Url 编码;

 

Scut:从PackageReader分析客户端协议规则

标签:

原文地址:http://www.cnblogs.com/Daniel-Liang/p/5768785.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!