TCP组包
来源:互联网 发布:单片机串口通信原理 编辑:程序博客网 时间:2024/06/14 19:29
MemoryStream MemoryStream; //此类内存字节流int HEAD_LENGTH = 8; //包体长度字段+协议的唯一标识。其中前4个字节用来标识包体长度,后四个字节用来标识协议ID。byte[] buffer = new byte[1024*10]; //开辟10k大小的缓冲区,用于接收数据TcpClient client = null;byte[] lockObj = new byte[1];BinaryReader reader; // 初始化void Init(){ client = new TcpClient(); memoryStream = new MemoryStream() reader = new BinaryReader(memoryStream); client.BeginConnect(127.0.0.1, 8888, new AsyncCallback(OnConnected), null);}// 连接建立的回调函数void OnConnected(IAsyncResult result){ if(client.Connected) { client.GetStream().BeginRead(buffer, 0 , 1024*10, new AsyncCallback(OnReadData),null); } else { Debug.LogError("网络异常"); }}// 当读到数据void OnReadData(IAsyncResult result){ int dataLength = 0; try { lock(lockObj) { dataLength = client.GetStream().EndRead(result); } // <span style="font-family: Arial, Helvetica, sans-serif;">组包处理</span> GeneratePacket(buffer, dataLength); // 继续读取 lock(lockObj) { // 首先要清空缓冲区 Array.Clear(buffer, 0, 1024*10); // 然后读取 client.GetStream().BeginRead(buffer, 0, 1024*10, new AsyncCallback(OnReadData), null); } } catch(Exception e) { Debug.LogError("网络异常"); }}// 组包处理 void GeneratePacket(byte[] bytes, int length) { memoryStream.Seek(0, SeekOrigin.End); // 文件末尾偏移0,即继续续写 memoryStream.Write(bytes, 0, length); // 写入length长度的数据 memoryStream.Seek(0, SeekOrigin.Begin); // 指针重置为0 // 数据包的长度 int dataLength = memoryStream.Length - memoryStream.Position; //当前数据包的长度-指针的起始位置 while(dataLength >= HEAD_LENGTH) { UInt32 messageDataLen = reader.ReadUInt32(); //这一步做完之后,memoryStream的Position,已经由原来位置,递增了4,因为reader读取4个字节 UInt32 protocolID = 0; dataLength = memoryStream.Length - memoryStream.Position if (dataLength >=messageDataLen+ 4) // 这里messageLen是数据部分,而+4,这个4protocolID占的四个字节 { protocolID = reader.ReadUInt32(); MemoryStream tmpStream = new MemoryStream(); BinaryWriter writer = new BinaryWriter(tmpStream); writer.Write(reader.ReadBytes(messageLen)); tmpStream.Seek(0, SeekOrigin.Begin); HandleMessage(protocolID, tmpStream); } else //如果数据不够,那么因为上面第一次reader.ReadUInt32()的时候,Position,已经由原来位置,递增了4,所以要减去4 { memoryStream.Position = memoryStream.Position - 4; break; } } dataLength = memoryStream.Length - memoryStream.Position; byte[] remainBytes = reader.ReadBytes(dataLength); memoryStream.SetLength(0); memoryStream.Write(remainBytes, 0, remainBytes.Length); //将剩余的数据包向前搬移。}// 处理消息void HandleMessage(Uint32 protocolID, MemoryStream paramData){ /// do sth...}
0 0
- tcp服务器组包
- TCP组包
- TCP组包问题
- TCP 组包和拆包算法
- TCP组包问题及处理方法
- 代码笔记 | TCP 组包和拆包算法
- TCP 组包和拆包算法-转载
- TCP协议-TCP包格式
- TCP粘包、拆包
- TCP粘包,拆包
- TCP粘包问题
- TCP包首部
- TCP粘包现象
- TCP粘包问题
- TCP/UDP包格式
- TCP粘包
- 【飞秋】TCP粘包
- TCP收包小结
- 解决未知视频广告导入问题
- Android入门——数据存储之SharedPreferences详解与应用
- 判断用户是安卓还是ios的php代码
- 二叉树的按层遍历
- opencv的一个神经网络例程(转自http://blog.sina.com.cn/s/blog_61e10f020101bv94.html)
- TCP组包
- 给EventBus增加订阅收到消息提醒,用AndroidStudio重新打包成Jar文件
- LinkedHashMap和HashMap的区别以及使用方法
- for 语句
- Android Studio中“非法字符\\65279,Error:(1, 10) 错误: 需要class, interface或enum”
- Part3:关联容器(二)&Part4:迭代器
- UVALive 3026 period(周期) kmp算法的应用
- Java技术内幕
- 2016.07.16【初中部 NOIP提高组 】模拟赛C总结