文章内容有错,请直接关闭~~~不要看了。丢人。

         private static Dictionary<string, Packet> cache = new Dictionary<string, Packet>();
private static Dictionary<string, object> lockers = new Dictionary<string, object>();
public List<pkReturn> Package(ChannelReceiveEventArgs e)
{ byte[] data = new byte[e.Data.Count];
Buffer.BlockCopy(e.Data.Array, , data, , e.Data.Count);
int leng = e.Data.Count; if (!lockers.ContainsKey(e.Channel.ID)) lockers[e.Channel.ID] = new object(); //创建锁
lock (lockers[e.Channel.ID])
{
if (data != null)
{
string id = e.Channel.ID;
try
{
if (cache.ContainsKey(id))
{//如果客户端ID存在,就把接收到的字节,和之前的字节合起来
cache[id].BufferTemp = coder.UnionBytes(cache[id].BufferTemp, data);
}
else
{//如果客户端ID不存在集合内,就新建一个放入集合
Packet pk = new Packet();
cache[id] = pk;
cache[id].BufferTemp = new byte[leng];
Buffer.BlockCopy(data, , cache[id].BufferTemp, , data.Length);//拷贝数据
}
//循环处理包
List<pkReturn> lists = new List<pkReturn>();
cache[id].BufferCom = null;
do
{
pkReturn model = new pkReturn();
if (cache[id].BufferTemp.Length >= ) //1-4字节包大小 4-6两字节指令
{
byte[] sizetemp = new byte[];//大小
Buffer.BlockCopy(cache[id].BufferTemp, , sizetemp, , );
int size = (int)BitConverter.ToUInt32(sizetemp, );
size = size + ;
byte[] cmd = new byte[];//指令
Buffer.BlockCopy(cache[id].BufferTemp, , cmd, , );
if (size < && size > )
{
model.PkSize = size;
model.Cmd = (int)BitConverter.ToUInt32(cmd, );
}
else
{
e.Channel.Dispose();
Remove(id);//小于0 有问题 要清理掉客户端
lists.Clear();
break;
}
//解析包
byte[] tempbytes = new byte[size];
if (size < cache[id].BufferTemp.Length)
{ Buffer.BlockCopy(cache[id].BufferTemp, , tempbytes, , size);//拷贝一个完整包 byte[] temp = new byte[cache[id].BufferTemp.Length - size];//保存剩下的字节
Buffer.BlockCopy(cache[id].BufferTemp, size, temp, , cache[id].BufferTemp.Length - size);
cache[id].BufferTemp = temp; model.Bytes = coder.UnifyDecrypt(tempbytes);//对完整包解密
lists.Add(model);
}
else if (size == cache[id].BufferTemp.Length)
{
Buffer.BlockCopy(cache[id].BufferTemp, , tempbytes, , size);//根据获得大小拷贝字节
model.Bytes = coder.UnifyDecrypt(tempbytes);//对完整包解密
lists.Add(model);
cache[id].BufferTemp = null;//清空数据缓冲区
break;
}
else if (size > cache[id].BufferTemp.Length)
{//如果包头标记大小大于缓冲区大小,跳出
break;
}
else
{
Console.WriteLine("任何条件都不符合");
} }
else
{
break;
}
} while (true);
return lists;
}
catch (Exception ex)
{
Remove(id);
e.Channel.Dispose();
Console.WriteLine("分包解析函数异常:" + ex.Message + " 定位:" + ex.StackTrace);
throw new ArgumentException("分包解析函数异常 定位:"+ex.Message);
}
}
else
{
Console.WriteLine("data 为null");
throw new ArgumentException("分包解析函数异常 data 为null");
//return null;
}
}
}

【原创】c# socket 粘包 其实。。。的更多相关文章

  1. Socket粘包问题

    这两天看csdn有一些关于socket粘包,socket缓冲区设置的问题,发现自己不是很清楚,所以查资料了解记录一下: 一两个简单概念长连接与短连接:1.长连接 Client方与Server方先建立通 ...

  2. C#下利用封包、拆包原理解决Socket粘包、半包问题(新手篇)

    介于网络上充斥着大量的含糊其辞的Socket初级教程,扰乱着新手的学习方向,我来扼要的教一下新手应该怎么合理的处理Socket这个玩意儿. 一般来说,教你C#下Socket编程的老师,很少会教你如何解 ...

  3. [转]关于Socket粘包问题

    这两天看csdn有一些关于socket粘包,socket缓冲区设置的问题,发现自己不是很清楚,所以查资料了解记录一下: 一两个简单概念长连接与短连接:1.长连接 Client方与Server方先建立通 ...

  4. 解决Socket粘包问题——C#代码

    解决Socket粘包问题——C#代码 前天晚上,曾经的一个同事问我socket发送消息如果太频繁接收方就会有消息重叠,因为当时在外面,没有多加思考 第一反应还以为是多线程导致的数据不同步导致的,让他加 ...

  5. Python socket粘包解决

    socket粘包: socket 交互send时,连续处理多个send时会出现粘包,soket会把两条send作为一条send强制发送,会粘在一起. send发送会根据recv定义的数值发送一个固定的 ...

  6. TCP Socket 粘包

     这两天看csdn有一些关于socket粘包,socket缓冲区设置的问题.发现自己不是非常清楚,所以查资料了解记录一下: 一两个简单概念长连接与短连接: 1.长连接 Client方与Server ...

  7. socket粘包现象加解决办法

    socket粘包现象分析与解决方案 简单远程执行命令程序开发(内容回顾) res = subprocess.Popen(cmd.decode('utf-8'),shell=True,stderr=su ...

  8. 百万年薪python之路 -- socket粘包问题解决

    socket粘包问题解决 1. 高大上版解决粘包方式(自定制包头) 整体的流程解释 整个流程的大致解释: 我们可以把报头做成字典,字典里包含将要发送的真实数据的描述信息(大小啊之类的),然后json序 ...

  9. Socket粘包问题终极解决方案—Netty版(2W字)!

    上一篇我们讲了<Socket粘包问题的3种解决方案>,但没想到评论区竟然炸了.介于大家的热情讨论,以及不同的反馈意见,本文就来做一个扩展和延伸,试图找到问题的最优解,以及消息通讯的最优解决 ...

  10. socket 粘包问题(转)

    https://www.v2ex.com/t/234785#reply3 1. 面向字节流的 IO 都有这个问题. socket 中 tcp 协议是面向流的协议,发送方发送和接收方的接收并不是一一对应 ...

随机推荐

  1. 027_nginx常见优化参数

    一.nginx.conf主配置文件 proxy_ignore_client_abort on; #不允许代理端主动关闭连接

  2. 缓存系列之二:CDN与其他层面缓存

    缓存系列之二:CDN与其他层面缓存 一:内容分发网络(Content Delivery Network),通过将服务内容分发至全网加速节点,利用全球调度系统使用户能够就近获取,有效降低访问延迟,提升服 ...

  3. SQL Server异常汇总

    1.特定用户名无法访问数据库 例如需要使用sa用户名访问School数据库失败,提示如下: (你要设置的)数据库--属性--文件--所用者设为Sa,回到用户映射查看,已勾选上. 还有一些情况 1)将登 ...

  4. form表单公用

    <?php /** * 后台总控制器 */ namespace app\common\controller; use think\Controller; use app\common\servi ...

  5. 配置nginx php上传大文件

    配置nginx php上传大文件: 1. 修改PHP配置文件中的三项:vim /usr/local/php/etc/php.ini 1.file_uploads 设为On,允许通过HTTP上传文件 2 ...

  6. 【进阶3-5期】深度解析 new 原理及模拟实现(转)

    这是我在公众号(高级前端进阶)看到的文章,现在做笔记 https://github.com/yygmind/blog/issues/24 new 运算符创建一个用户定义的对象类型的实例或具有构造函数的 ...

  7. 查看MySQL版本的命令及常用命令

    Windows / Linux 系统 前提是已经正确安装了 MySQL,打开 Windows 系统中的命令行工具(Win + R --> 输入 cmd 并按下回车键)--> 输入命令: m ...

  8. Confluence 6 发送 Confluence 通知到其他 Confluence 服务器

    你可以配置 Confluence 服务器向其他的 Confluence 服务器发送消息.在这种情况下,Confluence 服务器将不会显示 workbox. 希望发送消息到其他 Confluence ...

  9. Confluence 6 连接到 Jira 用户管理的限制

    当你在使用 JIRA 目录为用户目录的时候,请考虑下面的一些限制和建议. 不知道跨平台的多应用单点登录 当你使用 JIRA 为你的目录管理器的时候,系统将不能支持跨平台的单点登录.当 JIRA 用作目 ...

  10. Swift 给UITableView 写extension 时 报错 does not conform to protocol 'UITableViewDataSource'

    那是因为你没有实现 数据源和代理方法 实现下就好了 func tableView(_ tableView: UITableView, numberOfRowsInSection section: In ...