zoukankan      html  css  js  c++  java
  • HP-Socket快速入门:分包、粘包解析

    环境配置

    • vs2015
    • windows7 64位
    • hp-socket 5.0

    安装hp-socket

    新建控制台项目TelnetServer,打开Nuget管理工具,搜索hp-socket:

    安装成功后,会是如下的目录结构:

    HP-SOCKET是使用c++开发的,所以针对不同的平台生成不同dll。

    使用HP-SOCKET

    在我们的main函数中,输入如下代码,大多数对于socket的封装都差不多,需要实现以下事件,这里也就直接声明使用了。

    在这篇博客中,也只使用到了其中的三个。在实际项目中使用的时候,可按实际情况进行处理。

    处理分包、粘包数据

    使用socket进行通信,我们还需要跟调用方(客户端,我这里是智能硬件设备)协商好数据协议,也就是发送的数据包格式。比如一个完整数据包

    • {<order>#version#<data:123456789>}    // 结束符以回车换行为一个完整的包

     所谓的分包,就是我们的服务器接收到数据不是一次性到达的,比如先接收到整个包前面一部分:

    • {<order>#version#<data:12

    然后再接收到后面这部分数据:

    • 3456789>}

    同理,所谓的粘包,就是服务器接收到的数据是这样的:

    • {<order>#version#<data:123456789>} {<order>#version#<data

    关键代码

     1 private static HPSocketCS.HandleResult Server_OnAccept(IntPtr connId, IntPtr pClient)
     2         {
     3             Console.WriteLine("New connection come in " + connId);
     4             var obj = server.GetExtra<ClientSocketInfo>(connId);
     5             if (obj == null)//判断当前链接是否
     6             {
     7                 //存储分包对象信息
     8                 server.SetExtra(connId, new ClientSocketInfo
     9                 {
    10                     connId = connId
    11                 });
    12             }
    13             return HandleResult.Ok;
    14         }
    Server_OnAccept
    private static HPSocketCS.HandleResult Server_OnReceive(IntPtr connId, byte[] bytes)
            {
                Console.WriteLine("总数 {0}", count);
                var obj = server.GetExtra<ClientSocketInfo>(connId);
                try
                {
    
                    var msg = System.Text.Encoding.Default.GetString(bytes);
                    //按完整包结束符
     获取数据
                    var Arr = msg.Split(new string[] { "
    " }, StringSplitOptions.RemoveEmptyEntries).Where(d => !string.IsNullOrEmpty(d)).ToList();
                    foreach (var item in Arr)
                    {
                        Console.WriteLine("Item data {0}", item);
                        if (!item.Contains(">}"))//不包含>}说明是分包数据,存储到pack中
                        {
                            obj.pack += item;
                            Console.WriteLine("obj.pack {0}", obj.pack);
                        }
                        else
                        {
                            //如果包含>}并且pack不为空,说明是上个分包数据的结束数据
                            if (!string.IsNullOrEmpty(obj.pack))
                            {
                                var fullPack = obj.pack + item;                            
                                Console.WriteLine("FullPack {0}", fullPack);
                                //解析一个完整包后,清空当前句柄的分包数据
                                obj.pack = null;
                                Interlocked.Increment(ref pack_count);                           
                                Console.WriteLine("Clear Pack");
                            }
                            else
                            {
                                Interlocked.Increment(ref count);
                                //完整的包                            
                                Console.WriteLine("总数 {0}", count);
                                Console.WriteLine("分包_总数 {0}", pack_count);
                                var bCount = System.Text.Encoding.Default.GetBytes(count.ToString());
                                server.Send(connId, bCount, bCount.Length);
                                Console.WriteLine("A Full package!");
                                Console.WriteLine("解析数据");
                            }
                        }
                    }
    
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                    return HandleResult.Error;
                }
                
                return HandleResult.Ok;
            }
    Server_OnReceive

    希望这篇文章能帮助到大家。

    源码下载

    密码 iuw8

  • 相关阅读:
    企业视频会议EasyRTC视频云服务是如何满足不同企业多场景直播的?
    TSINGSEE青犀视频H265网页播放器EasyPlayerPro-Win如何通过配置文件实现自动播放等功能?
    TSINGSEE青犀视频自主研发H265播放器EasyPlayerPro-Win C++如何获取软件版本信息源码
    RTMP视频直播点播平台EasyDSS及企业视频通话会议系统EasyRTC内启动nginx 配置重定向功能介绍
    面向对象程序设计上机练习二(函数模板)
    2014暑假ACM训练总结
    codeforces 之 Little Pigs and Wolves
    SDUT 2766 小明传奇2
    0-1背包的总结
    POJ 2063 Investment (完全背包)
  • 原文地址:https://www.cnblogs.com/liangxiarong/p/8762573.html
Copyright © 2011-2022 走看看