【原创】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 协议是面向流的协议,发送方发送和接收方的接收并不是一一对应 ...
随机推荐
- eclipse 迁移项目 乱码
eclipse 迁移项目总是乱码问题,网上解决都无非是把workspace.项目.文件等改成utf-8,但总是不好使,因为原来有的文件类型还是要改成原来的编码格式,可以使用文本工具如notepad打开 ...
- Excel 2013 表格自用技巧
参考 Excel表格的基本操作(精选36个技巧) Excel2013基本用法 关于VLOOKUP函数 目录 快速复制单元格 单元格内强制换行 锁定标题行 查找重复值 万元显示 单元格中显示001 按月 ...
- 用Cordova打包Vue-vux项目
技术搭建:vue + vux 首先推荐阅读这篇文章,写的已经很详细了:https://www.jianshu.com/p/25d797b983cd 此处记录下我按照这篇文章打包的时候报的一些错误,方便 ...
- ionic配置
这个问题在升级ionic2的时候可能会遇到,不一定是windows,但是解决办法都是一样的,其实很简单,就是sass不支持当前的环境,那么在当前环境重新安装一下就好了 先卸载: npm uninsta ...
- 带jdk15类似的jar配置
针对部分jar文件名带有jdk15结尾的依赖配置时,需要添加<classifier>标签进行区分 比如针对:json-lib-2.4-jdk15.jar的jar依赖配置 <depen ...
- PHP导入导出csv文件 Summer-CSV
2017年11月9日09:25:56 根据项目实践总结的一个类文件, mac/win下没乱码 简体中文 默认从gb2312转到utf-8 https://gitee.com/myDcool/PHP-C ...
- 转载:Eureka 开发时快速剔除失效服务
原文地址:https://www.cnblogs.com/flying607/p/8494568.html 服务端配置: # 关闭保护机制 eureka.server.enable-self-pres ...
- 优秀员工的修炼——通往专家、管理之路
(一)好员工的素质 好员工的类型有很多种,尝试着抽象出一个定义吧--好员工是那些主管分配其任务放心.同事喜欢与其共事.对自己工作负责.志在自我提升和价值实现的人.知识经济时代,好员工首先是做好自我管理 ...
- spring mvc数据绑定与表单标签库
Book类为 package org.shaoxiu; public class Book { private String id; private String name; public Book( ...
- [正则表达式]匹配Unicode
一.PHP[PCRE]之Unicode PCRE支持的16进制字符编码转义符有 \x00-\xFF,或\x{num},num为任意位16进制数 但并不支持\u0000-\uFFFF这的形式 PCRE运 ...