博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
网络数据处理缓冲区和缓冲池实现
阅读量:5910 次
发布时间:2019-06-19

本文共 4069 字,大约阅读时间需要 13 分钟。

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

缓冲区

其实构造一个缓冲区非常简单,根据需分本相关大小的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,根据对象的需要把信息分别写入多个缓冲区和在多个缓冲区中读取信息还原对象。

c#组件设计交流群:47164588 
c# socket :136485198 

转载地址:http://sztpx.baihongyu.com/

你可能感兴趣的文章
装饰器类学习小结
查看>>
初次使用VS2010基于C++开发项目碰到的问题及解决方法
查看>>
JDK配置
查看>>
占用CPU时间,调用函数,点亮LED的C语言程序 【原创】
查看>>
C 语言 排序算法,冒泡排序,选择排序,插入排序,二分查找
查看>>
redmine和testlink的迁移和集成
查看>>
Xmonitor工具介绍
查看>>
MySQL 的相关介绍
查看>>
Android TextView跑马灯效果
查看>>
read 命令详解
查看>>
我的友情链接
查看>>
HTTP协议之Content-Encoding
查看>>
postgresql客户端命令之口令文件
查看>>
java 实验五 String 常方法
查看>>
Roman to Integer leetcode
查看>>
python中使用xlrd、xlwt操作excel表格详解
查看>>
重做日志与归档日志有什么区别
查看>>
Linux的经典shell命令整理
查看>>
我的友情链接
查看>>
克隆的CentOS6.6系统,网卡显示不存在的解决方法
查看>>