网络数据处理缓冲区和缓冲池实现

简介:

在编写网络应用的时候数据缓冲区是应该比较常用的方式,主要用构建一个内存区用于存储发送的数据和接收的数据;为了更好的利用已有数据缓冲区所以构造一个缓冲池来存放相关数据方便不同连接更好地利用缓冲区,节省不停的构造新的缓冲区所带的损耗问题。

缓冲区

其实构造一个缓冲区非常简单,根据需分本相关大小的byte数组即可;既然是用于存放数据那就自然要实现读和写方法,看一下具体实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
public  class  DataBuffer : IDisposable
     {
         public  byte [] Data;
         private  int  mLength;
         private  int  mPostion = 0;
         internal  int  mCount = 0;
         
         public  DataBuffer( byte [] data)
         {
             Data = data;
             mLength = data.Length;
             mPostion = 0;
             mCount = data.Length;
         }
 
         public  DataBuffer( int  length)
         {
             mLength = length;
             Data = new  byte [length];
         }
         public  void  From(Array source, int  index, int  count)
         {
             Array.Copy(source, index, Data, 0, count);
             mPostion = 0;
             mCount = count;
         }
         public  int  Write( byte [] data)
         {
             return  Write(data, 0);
         }
         public  int  Write( byte [] data, int  index)
         {
             int  count = 0;
             if  (mPostion + (data.Length-index) > mLength)
             {
                 count = mLength - mPostion;
             }
             else
             {
                 count = data.Length - index;
             }
             if  (count > 0)
             {
                 Array.Copy(data, index, Data, mPostion, count);
 
                 mPostion += count;
                 mCount += count;
             }
             return  count;
         }
         public  ArraySegment< byte > Read( int  count)
         {
             int  end = count;
             if  (mPostion + count > mCount)
                 end = mCount - mPostion;
            
             ArraySegment< byte > result= new  ArraySegment< byte >(Data, mPostion, end);
             mPostion += end;
             return  result;
         }
         public  void  Seek()
         {
             Seek(0);
         }
         public  void  Seek( int  postion)
         {
             mPostion = 0;
         }
         public  ArraySegment< byte > GetSegment()
         {
             return  new  ArraySegment< byte >(Data, 0, mCount);
         }
         internal  BufferPool Pool
         {
             get ;
             set ;
         }
         public  void  Dispose()
         {
             if  (Pool != null )
             {
                 mPostion = 0;
                 mCount = 0;
                 Pool.Push( this );
             }
         }
     }

 为了方便使用,Buffer实现了IDisposable接口,其作为就是当释放的时候把Buffer放回到Pool里.

Buffer提供了两个方法分别是Write和Read用于写和读数据,由于缓冲区有大小限制,所以在写的时候会返回一个成功写入的数量;而read则返回一个ArraySegment<byte>用于描述其位置。为什么要这样做呢,其实有些情况一个数据成员会被写入到不同的缓冲区,当读出来的时候就会存要在多个缓冲区中获取。

缓冲池

缓冲池用于发放和回收级冲区,实现一个重用的目的。池的实现并不复杂,封装一个简单的队列操作即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
public  class  BufferPool : IDisposable
     {
         private  static  List<BufferPool> mPools = new  List<BufferPool>();
         private  static  int  mIndex = 0;
         public  static  void  Setup( int  pools, int  buffers)
         {
             Setup(pools, buffers, 2048);
         }
         public  static  void  Setup( int  pools, int  buffers, int  bufferlength)
         {
             lock  (mPools)
             {
                 for  ( int  i = 0; i < pools; i++)
                 {
                     mPools.Add( new  BufferPool(buffers, bufferlength));
                 }
             }
         }
         public  static  void  Clean()
         {
             lock  (mPools)
             {
                 foreach  (BufferPool item in  mPools)
                 {
                     item.Dispose();
                 }
                 mPools.Clear();
             }
         }
         public  static  BufferPool GetPool()
         {
             lock  (mPools)
             {
                 if  (mIndex == mPools.Count)
                 {
                     mIndex = 0;
                 }
                 return  mPools[mIndex];
             }
         }
         Queue<DataBuffer> mBuffers;
         private  int  mBufferLength;
         public  BufferPool( int  count, int  bufferlength)
         {
             mBufferLength = bufferlength;
             mBuffers = new  Queue<DataBuffer>(count);
             for  ( int  i = 0; i < count; i++)
             {
                 mBuffers.Enqueue(createBuffer(bufferlength));
             }
         }
         private  DataBuffer createBuffer( int  length)
         {
             DataBuffer item = new  DataBuffer(length);
             item.Pool = this ;
             return  item;
         }
         public  DataBuffer Pop()
         {
             lock  (mBuffers)
             {
                 return  mBuffers.Count > 0 ? mBuffers.Dequeue() : createBuffer(mBufferLength);
             }
         }
         public  void  Push(DataBuffer buffer)
         {
             lock  (mBuffers)
             {
                 mBuffers.Enqueue(buffer);
             }
         }
         private  bool  mDisposed = false ;
         private  void  OnDispose()
         {
             lock  (mBuffers)
             {
                 while  (mBuffers.Count > 0)
                 {
                     mBuffers.Dequeue().Pool = null ;
                 }
             }
         }
         public  void  Dispose()
         {
             lock  ( this )
             {
                 if  (!mDisposed)
                 {
                     OnDispose();
                     mDisposed = true ;
                 }
             }
         }
     }

BufferPool实现了几个静态方法

Setup

主要目的是用于构造多个缓冲池,缓冲区数量和缓冲区大小。为什么会考虑多个池呢,主要原因是在高并发的来分配处理减低池的负载。

Clean

        用于清除释放缓冲池

GetPool

平均地分发缓冲池给使用者

    一个简单的数据缓冲区和数据缓冲池已经实现了,在后面的文章里会讲述如何构造BufferWriter和BufferReader,根据对象的需要把信息分别写入多个缓冲区和在多个缓冲区中读取信息还原对象。

目录
相关文章
|
存储 JavaScript 前端开发
js实现灵活下载和预览网络链接pdf文件
js实现灵活下载和预览网络链接pdf文件
856 0
|
4月前
|
存储 缓存 移动开发
日常小知识点之用户层网络缓冲区(固定内存,ringbuffer,chainbuffer)
日常小知识点之用户层网络缓冲区(固定内存,ringbuffer,chainbuffer)
61 0
|
5月前
|
存储 网络协议 Linux
网络缓冲区
网络缓冲区
41 0
|
Web App开发 存储 网络协议
一篇文章帮你拿下面试八股文之网络三次握手四次挥手, HTTP超文本传输协议重点理论刨析到实现简单的HTTP服务, 思考着图解着学习网络 (咱不死记硬背)
一篇文章帮你拿下面试八股文之网络三次握手四次挥手, HTTP超文本传输协议重点理论刨析到实现简单的HTTP服务, 思考着图解着学习网络 (咱不死记硬背)
一篇文章帮你拿下面试八股文之网络三次握手四次挥手, HTTP超文本传输协议重点理论刨析到实现简单的HTTP服务, 思考着图解着学习网络 (咱不死记硬背)
|
传感器
如何使用Simulink实现一个分布式电子控制单元 (ECU) 网络
如何使用Simulink实现一个分布式电子控制单元 (ECU) 网络
如何使用Simulink实现一个分布式电子控制单元 (ECU) 网络
|
存储 Java 数据库
JAVA实现网络多线程编程小游戏开发
实验总结:五子棋是一个很简单的游戏,但是如果认真对待,一个代码一个代码的去研究,会收获到很多知识,会打好学习基础。方便以后开发更高、更难的项目时打下稳固的基础。在自己开发的过程中会有各种意想不到的bug,通过查阅资料及询问老师同学进行解决对本身的一个代码能力会有一个质的增长,同时这也是一个非常快乐的过程。有进步,总归是好事。
JAVA实现网络多线程编程小游戏开发
|
XML 存储 JSON
Android网络与数据存储——网络编程数据处理(网络请求解析Json,解析xml)
Android网络与数据存储——网络编程数据处理(网络请求解析Json,解析xml)
228 0
|
机器学习/深度学习 传感器 算法
【信号分类】基于长短期记忆 (LSTM) 网络实现 OFDM 系统的信号检测附matlab代码
【信号分类】基于长短期记忆 (LSTM) 网络实现 OFDM 系统的信号检测附matlab代码
|
机器学习/深度学习 传感器 算法
【DBN分类】基于麻雀算法优化深度置信网络SSA-DBN实现数据分类附matlab代码
【DBN分类】基于麻雀算法优化深度置信网络SSA-DBN实现数据分类附matlab代码
【DBN分类】基于麻雀算法优化深度置信网络SSA-DBN实现数据分类附matlab代码
|
机器学习/深度学习 C++ Python
图注意力网络入门:从数学理论到到NumPy实现
图注意力网络入门:从数学理论到到NumPy实现
203 0
图注意力网络入门:从数学理论到到NumPy实现

热门文章

最新文章