环境配置

  • 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快速入门:分包、粘包解析的更多相关文章

  1. 6.2 socket 流协议与粘包

    TCP IP协议是流协议,对上层协议来讲是没有边界的,主机A发送两个消息M1和M2,如下图所示: 主机A发送了M1和M2,主机B在接收时有4种情况: 1.先收了M1,又收了M2 2.M1.M2一起收到 ...

  2. TCP网络通讯如何解决分包粘包问题(有模拟代码)

    TCP作为常用的网络传输协议,数据流解析是网络应用开发人员永远绕不开的一个问题. TCP数据传输是以无边界的数据流传输形式,所谓无边界是指数据发送端发送的字节数,在数据接收端接受时并不一定等于发送的字 ...

  3. python笔记8 socket(TCP) subprocess模块 粘包现象 struct模块 基于UDP的套接字协议

    socket 基于tcp协议socket 服务端 import socket phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 买 ...

  4. Socket编程 Tcp和粘包

    大多数程序员都要接触网络编程,Web开发天天和http打交道.稍微底层一点的程序员,就是TCP/UDP . 对程序员来说,Tcp/udp的核心是Socket编程. 我的浅薄的观点---------理解 ...

  5. day8---多线程socket 编程,tcp粘包处理

    复习下socket 编程的步骤: 服务端:   1 声明socket 实例 server = socket.socket()  #括号里不写  默认地址簇使用AF_INET  即 IPv4       ...

  6. c# Socket通讯中关于粘包,半包的处理,加分割符

    using System; using System.Collections.Generic; using System.Text; using System.Net.Sockets; using S ...

  7. python socket网络编程之粘包问题详解

    一,粘包问题详情 1,只有TCP有粘包现象,UDP永远不会粘包 你的程序实际上无权直接操作网卡的,你操作网卡都是通过操作系统给用户程序暴露出来的接口,那每次你的程序要给远程发数据时,其实是先把数据从用 ...

  8. Python开发【socket篇】解决粘包

    客户端 import os import json import struct import socket sk = socket.socket() sk.connect(('127.0.0.1',8 ...

  9. 11.1、socket连接中的粘包、精确传输问题

    粘包: 发生原因: 当调用send的时候,数据并不是即时发给客户端的.而是放到了系统的socket发送缓冲区里,等缓冲区满了.或者数据等待超时了,数据才会发送,所以有时候发送太快的话,前一份数据还没有 ...

随机推荐

  1. Android 系统当中各种尺寸单位的定义及使用

    一,Android 各种标尺单位的含义: px:表示屏幕实际的象素.例如,320*480的屏幕在横向有320个象素,在纵向有480个象素.pt:表示一个点,是屏幕的物理尺寸.大小为1英寸的1/72.i ...

  2. Android:Field can be converted to a local varible.

    背景 使用 Android Studio 开发 Android 有一段时间了,偶尔会碰到 AS 在一些私有变量上有黄色高亮提示Field can be converted to a local var ...

  3. 浅谈C++中的友元关系

    在封装中C++类数据成员大多情况是private属性:但是如果接口采用多参数实现肯定影响程序效率:然而这时候如果外界需要频繁访问这些私有成员,就不得不需要一个既安全又理想的"后门" ...

  4. iOS中 最新支付宝支付(AliPay) 韩俊强的博客

    每日更新关注:http://weibo.com/hanjunqiang  新浪微博 现在的支付方式一般有三种, 支付宝, 微信, 网银. 个人觉得最简单易用的还是支付宝, 微信虽然看起来币支付宝要简单 ...

  5. HTTP请求方法

    HTTP请求方法 根据HTTP标准,HTTP请求可以使用多种请求方法. HTTP1.0定义了三种请求方法: GET, POST 和 HEAD方法. HTTP1.1新增了五种请求方法:OPTIONS, ...

  6. [C++学习历程]Visual Studio 2010 中文旗舰版 安装

    作者: 苏生米沿 本文地址:http://blog.csdn.net/sushengmiyan/article/details/19765441 要开始学习C++了,先装个开发环境吧,没有选择最新的2 ...

  7. 面试常用算法总结——排序算法(java版)

    排序算法 重要性不言而喻,很多算法问题往往选择一个好的排序算法往往问题可以迎刃而解 1.冒泡算法 冒泡排序(Bubble Sort)也是一种简单直观的排序算法.它重复地走访过要排序的数列,一次比较两个 ...

  8. 从JDK源码角度看线程池原理

    "池"技术对我们来说是非常熟悉的一个概念,它的引入是为了在某些场景下提高系统某些关键节点性能,最典型的例子就是数据库连接池,JDBC是一种服务供应接口(SPI),具体的数据库连接实 ...

  9. JAVA之旅(二十)—HashSet,自定义存储对象,TreeSet,二叉树,实现Comparator方式排序,TreeSet小练习

    JAVA之旅(二十)-HashSet,自定义存储对象,TreeSet,二叉树,实现Comparator方式排序,TreeSet小练习 我们继续说一下集合框架 Set:元素是无序(存入和取出的顺序不一定 ...

  10. 谈谈Ext JS组件之引子

    Ext JS组件,对于Ext JS开发人员来说,应当不会陌生,毕竟做开发,都必须与它打交道.对于这样一个大家都熟悉的东西,为什么要用一个专题的形式来写呢?是否有这方面的需要?还不如去写点使用技巧? 确 ...