socket Php 粘包,HP-Socket快速入门:分包、粘包解析

环境配置

vs2015

windows7 64位

hp-socket 5.0

安装hp-socket

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

dd0e65c2a415b64bf7fd4766ee37e757.png

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

30aea0d6de0c34ef1928d2ab6d657b0d.png

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

使用HP-SOCKET

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

17942412b5f1f59d27ab2935e1c88eda.png

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

处理分包、粘包数据

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

{#version#<123456789>}\r\n    // 结束符以回车换行为一个完整的包123456789>

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

{#version#<12>

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

3456789>}\r\n

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

{#version#<123456789>}\r\n{#version#

关键代码

27a0bc668b437ba1bbe5c77190226563066.jpg

cd2640103de1760acba588d1346f3581ef3.jpg

1 private staticHPSocketCS.HandleResult Server_OnAccept(IntPtr connId, IntPtr pClient)2 {3 Console.WriteLine("New connection come in" +connId);4 var obj = server.GetExtra(connId);5 if (obj == null)//判断当前链接是否

6 {7 //存储分包对象信息

8 server.SetExtra(connId, newClientSocketInfo9 {10 connId =connId11 });12 }13 returnHandleResult.Ok;14 }

Server_OnAccept

aee8be0c4e68fc36eba1db2fc534930bc35.jpg

19ba77612d7c683316e906383845c5c6546.jpg

private static HPSocketCS.HandleResult Server_OnReceive(IntPtr connId, byte[] bytes)

{

Console.WriteLine("总数 {0}", count);var obj = server.GetExtra(connId);try{var msg =System.Text.Encoding.Default.GetString(bytes);//按完整包结束符\r\n 获取数据

var Arr = msg.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries).Where(d => !string.IsNullOrEmpty(d)).ToList();foreach (var item inArr)

{

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(refpack_count);

Console.WriteLine("Clear Pack");

}else{

Interlocked.Increment(refcount);//完整的包

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);returnHandleResult.Error;

}returnHandleResult.Ok;

}

Server_OnReceive

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

密码 iuw8

123456789>12>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值