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>}\r\n // 结束符以回车换行为一个完整的包
所谓的分包,就是我们的服务器接收到数据不是一次性到达的,比如先接收到整个包前面一部分:
- {<order>#version#<data:12
然后再接收到后面这部分数据:
- 3456789>}\r\n
同理,所谓的粘包,就是服务器接收到的数据是这样的:
- {<order>#version#<data:123456789>}\r\n{<order>#version#<data
关键代码
private static HPSocketCS.HandleResult Server_OnAccept(IntPtr connId, IntPtr pClient)
{
Console.WriteLine("New connection come in " + connId);
var obj = server.GetExtra<ClientSocketInfo>(connId);
if (obj == null)//判断当前链接是否
{
//存储分包对象信息
server.SetExtra(connId, new ClientSocketInfo
{
connId = connId
});
}
return HandleResult.Ok;
}
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);
//按完整包结束符\r\n 获取数据
var Arr = msg.Split(new string[] { "\r\n" }, 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
HP-Socket快速入门:分包、粘包解析的更多相关文章
- 6.2 socket 流协议与粘包
TCP IP协议是流协议,对上层协议来讲是没有边界的,主机A发送两个消息M1和M2,如下图所示: 主机A发送了M1和M2,主机B在接收时有4种情况: 1.先收了M1,又收了M2 2.M1.M2一起收到 ...
- TCP网络通讯如何解决分包粘包问题(有模拟代码)
TCP作为常用的网络传输协议,数据流解析是网络应用开发人员永远绕不开的一个问题. TCP数据传输是以无边界的数据流传输形式,所谓无边界是指数据发送端发送的字节数,在数据接收端接受时并不一定等于发送的字 ...
- python笔记8 socket(TCP) subprocess模块 粘包现象 struct模块 基于UDP的套接字协议
socket 基于tcp协议socket 服务端 import socket phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 买 ...
- Socket编程 Tcp和粘包
大多数程序员都要接触网络编程,Web开发天天和http打交道.稍微底层一点的程序员,就是TCP/UDP . 对程序员来说,Tcp/udp的核心是Socket编程. 我的浅薄的观点---------理解 ...
- day8---多线程socket 编程,tcp粘包处理
复习下socket 编程的步骤: 服务端: 1 声明socket 实例 server = socket.socket() #括号里不写 默认地址簇使用AF_INET 即 IPv4 ...
- c# Socket通讯中关于粘包,半包的处理,加分割符
using System; using System.Collections.Generic; using System.Text; using System.Net.Sockets; using S ...
- python socket网络编程之粘包问题详解
一,粘包问题详情 1,只有TCP有粘包现象,UDP永远不会粘包 你的程序实际上无权直接操作网卡的,你操作网卡都是通过操作系统给用户程序暴露出来的接口,那每次你的程序要给远程发数据时,其实是先把数据从用 ...
- Python开发【socket篇】解决粘包
客户端 import os import json import struct import socket sk = socket.socket() sk.connect(('127.0.0.1',8 ...
- 11.1、socket连接中的粘包、精确传输问题
粘包: 发生原因: 当调用send的时候,数据并不是即时发给客户端的.而是放到了系统的socket发送缓冲区里,等缓冲区满了.或者数据等待超时了,数据才会发送,所以有时候发送太快的话,前一份数据还没有 ...
随机推荐
- 01_MyBatis EHCache集成及所需jar包,ehcache.xml配置文件参数配置及mapper中的参数配置
1 与mybatis集成时需要的jar ehcache-core-2.6.5.jar mybatis-ehcache-1.0.2.jar Mybatis.日志.EHCache所需要的jar包如下 ...
- 当图片验证码遇上JSP
今天看到了一个关于使用JSP方式生成图片验证码 的小例子,感觉真的是很不错,拿来分享一下. 原理 对于图片验证码,我们在审查元素的时候会方便的看出是<img src="#" ...
- java的list几种实现方式的效率(ArrayList、LinkedList、Vector、Stack),以及 java时间戳的三种获取方式比较
一.list简介 List列表类,顺序存储任何对象(顺序不变),可重复. List是继承于Collection的接口,不能实例化.实例化可以用: ArrayList(实现动态数组),查询快(随意访问或 ...
- linux 定时任务详解 按秒设定
实现linux定时任务有:cron.anacron.at等,这里主要介绍cron服务. 名词解释: cron是服务名称,crond是后台进程,crontab则是定制好的计划任务表. 软件包安装: 要使 ...
- 如何在Cocos2D 1.0 中掩饰一个精灵(二)
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 让我们开始吧 打开Xcode,从New Project中选择co ...
- 给你的流添加缓冲装置——字节块ByteChunk
这是一个很重要的一个字节数组处理缓冲工具,它封装了字节缓冲器及对字节缓冲区的操作,包括对缓冲区的写入.读取.扩展缓冲区大小等等,另外还提供相应字符编码的转码操作.此工具让缓冲操作变得更加方便,除了缓冲 ...
- Maven项目中获取classpath和资源文件的路径
假设资源文件放在maven工程的 src/main/resources 资源文件夹下,源码文件放在 src/main/java/下, 那么java文件夹和resources文件夹在运行时就是cl ...
- UNIX环境高级编程——管道和FIFO限制
系统加于管道和FIFO的唯一限制为: OPEN_MAX 一个进程在任意时刻打开的最大描述符数: PIPE_BUF 可原子的写往一个管道或FIFO的最大数据量. OPEN_MAX的值 ...
- 海量数据挖掘MMDS week5: 聚类clustering
http://blog.csdn.net/pipisorry/article/details/49427989 海量数据挖掘Mining Massive Datasets(MMDs) -Jure Le ...
- Mybatis逻辑分页原理解析RowBounds
Mybatis提供了一个简单的逻辑分页使用类RowBounds(物理分页当然就是我们在sql语句中指定limit和offset值),在DefaultSqlSession提供的某些查询接口中我们可以看到 ...