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

简介:

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

缓冲区

其实构造一个缓冲区非常简单,根据需分本相关大小的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文件
1091 0
|
5月前
|
关系型数据库 MySQL 数据库
实时计算 Flink版操作报错合集之网络缓冲池(NetworkBufferPool)中可用内存不足,该如何解决
在使用实时计算Flink版过程中,可能会遇到各种错误,了解这些错误的原因及解决方法对于高效排错至关重要。针对具体问题,查看Flink的日志是关键,它们通常会提供更详细的错误信息和堆栈跟踪,有助于定位问题。此外,Flink社区文档和官方论坛也是寻求帮助的好去处。以下是一些常见的操作报错及其可能的原因与解决策略。
|
1月前
|
数据采集 监控 数据可视化
Fortran 在单位网络监控软件数据处理中的应用
在数字化办公环境中,Fortran 语言凭借其高效性和强大的数值计算能力,在单位网络监控软件的数据处理中展现出独特优势。本文介绍了 Fortran 在数据采集、预处理和分析可视化三个阶段的应用,展示了其在保障网络安全稳定运行和有效管理方面的价值。
52 10
|
4月前
|
数据采集 资源调度 JavaScript
Node.js 适合做高并发、I/O密集型项目、轻量级实时应用、前端构建工具、命令行工具以及网络爬虫和数据处理等项目
【8月更文挑战第4天】Node.js 适合做高并发、I/O密集型项目、轻量级实时应用、前端构建工具、命令行工具以及网络爬虫和数据处理等项目
63 5
|
6月前
|
缓存 C++ 索引
用户态网络缓冲区设计
用户态网络缓冲区设计
45 1
|
7月前
|
存储 XML 前端开发
【Flutter前端技术开发专栏】Flutter中的网络请求与数据处理
【4月更文挑战第30天】本文介绍了Flutter开发中的网络请求和数据处理。 Flutter开发者可选择http(官方库)或dio(功能更强大)进行网络请求。http库简单易用,dio支持更多功能如拦截器。数据处理涉及JSON和XML解析,数据存储可选SharedPreferences或Hive,数据传递推荐使用InheritedWidget或Provider状态管理库。了解这些知识点能提升Flutter开发效率。
180 0
【Flutter前端技术开发专栏】Flutter中的网络请求与数据处理
|
7月前
|
数据采集 机器学习/深度学习 数据挖掘
网络数据处理中的NumPy应用实战
【4月更文挑战第17天】本文介绍了NumPy在网络数据处理中的应用,包括数据预处理、流量分析和模式识别。通过使用NumPy进行数据清洗、格式化和聚合,以及处理时间序列数据和计算统计指标,可以有效进行流量分析和异常检测。此外,NumPy还支持相关性分析、周期性检测和聚类分析,助力模式识别。作为强大的科学计算库,NumPy在处理日益增长的网络数据中发挥着不可或缺的作用。
|
7月前
|
机器学习/深度学习 存储 算法
长短时记忆网络(LSTM)在序列数据处理中的优缺点分析
长短时记忆网络(LSTM)在序列数据处理中的优缺点分析
1254 1
长短时记忆网络(LSTM)在序列数据处理中的优缺点分析
|
7月前
|
存储 缓存 移动开发
日常小知识点之用户层网络缓冲区(固定内存,ringbuffer,chainbuffer)
日常小知识点之用户层网络缓冲区(固定内存,ringbuffer,chainbuffer)
153 0
|
存储 网络协议 Linux
网络缓冲区
网络缓冲区
74 0