【原创】c# socket 粘包 其实。。。
文章内容有错,请直接关闭~~~不要看了。丢人。
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 粘包 其实。。。的更多相关文章
- Socket粘包问题
这两天看csdn有一些关于socket粘包,socket缓冲区设置的问题,发现自己不是很清楚,所以查资料了解记录一下: 一两个简单概念长连接与短连接:1.长连接 Client方与Server方先建立通 ...
- C#下利用封包、拆包原理解决Socket粘包、半包问题(新手篇)
介于网络上充斥着大量的含糊其辞的Socket初级教程,扰乱着新手的学习方向,我来扼要的教一下新手应该怎么合理的处理Socket这个玩意儿. 一般来说,教你C#下Socket编程的老师,很少会教你如何解 ...
- [转]关于Socket粘包问题
这两天看csdn有一些关于socket粘包,socket缓冲区设置的问题,发现自己不是很清楚,所以查资料了解记录一下: 一两个简单概念长连接与短连接:1.长连接 Client方与Server方先建立通 ...
- 解决Socket粘包问题——C#代码
解决Socket粘包问题——C#代码 前天晚上,曾经的一个同事问我socket发送消息如果太频繁接收方就会有消息重叠,因为当时在外面,没有多加思考 第一反应还以为是多线程导致的数据不同步导致的,让他加 ...
- Python socket粘包解决
socket粘包: socket 交互send时,连续处理多个send时会出现粘包,soket会把两条send作为一条send强制发送,会粘在一起. send发送会根据recv定义的数值发送一个固定的 ...
- TCP Socket 粘包
这两天看csdn有一些关于socket粘包,socket缓冲区设置的问题.发现自己不是非常清楚,所以查资料了解记录一下: 一两个简单概念长连接与短连接: 1.长连接 Client方与Server ...
- socket粘包现象加解决办法
socket粘包现象分析与解决方案 简单远程执行命令程序开发(内容回顾) res = subprocess.Popen(cmd.decode('utf-8'),shell=True,stderr=su ...
- 百万年薪python之路 -- socket粘包问题解决
socket粘包问题解决 1. 高大上版解决粘包方式(自定制包头) 整体的流程解释 整个流程的大致解释: 我们可以把报头做成字典,字典里包含将要发送的真实数据的描述信息(大小啊之类的),然后json序 ...
- Socket粘包问题终极解决方案—Netty版(2W字)!
上一篇我们讲了<Socket粘包问题的3种解决方案>,但没想到评论区竟然炸了.介于大家的热情讨论,以及不同的反馈意见,本文就来做一个扩展和延伸,试图找到问题的最优解,以及消息通讯的最优解决 ...
- socket 粘包问题(转)
https://www.v2ex.com/t/234785#reply3 1. 面向字节流的 IO 都有这个问题. socket 中 tcp 协议是面向流的协议,发送方发送和接收方的接收并不是一一对应 ...
随机推荐
- [MySQL]group by 与 if 的统计技巧
group by查询旨在把某字段中相同的记录合并成一列,查询结果可受count(),sum()等统计函数影响 如下表 id totalclick validclick 1 3 1 2 3 1 3 5 ...
- IPFS环境安装
IPFS是一个分布式的P2P的协议,可能会取代这个http,全球的点都可能存储这个数据 IPFS搭建环境 1.首先是下载节点软件到官网下载windows版本的ipfs节点软件,如果不能访问官网的话,可 ...
- disk2vhd-----将windows系统转换成虚拟镜像格式
工具介绍 下载url:http://technet.microsoft.com/en-us/sysinternals/ee656415.aspx disk2vhd是一个非常小的P2V转换工具,可以将你 ...
- Sql语句分页,有待优化
封装成存储过程,但是有点小问题,如果有弄好了的朋友可留言,谢谢了,我只提供了一个模版哈(也是我想实现的功能) create procedure paging_procedure ( @pageInde ...
- 32)django-modelform
一:mdoelform modelform是model和form结合 model+form =>验证+数据库 class A(model): user= pass= Form: class Lo ...
- 体验go语言的风骚式编程
最近想搞搞后台开发,话说注意力就转移到了公司用的golang.用Go做微服务比较方便,或许是因为golang强悍的语法吧,看到go的语法,自己已被深深的吸引.关于学习后台如何选择可以参考<做后台 ...
- 不能够连接到主机(名称为localhost)上的MySQL服务”
不能够连接到主机(名称为localhost)上的MySQL服务” -如果是服务未启动.那么就右键‘计算机’---->管理--->服务和应用程序---->服务,在右侧的栏目中找到名称为 ...
- C# 将Excel转换为PDF
C# 将Excel转换为PDF 转换场景 将Excel转换为PDF是一个很常用的功能,常见的转换场景有以下三种: 转换整个Excel文档到PDF转换Excel文档的某一个工作表到PDF转换Excel文 ...
- 第十八单元 nginx服务
安装python 源 wget 网上下载 原码 编译 安装的流程 (gcc glic) 版本更新时起冲突,删除原版本(或者reinstall重新安装) 可执行文件运行 ./ 软连接 查看 ...
- Python计算器实操
要求: 开发一个简单的python计算器 实现加减乘除及拓号优先级解析 用户输入 1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * ...