在编写网络应用的时候数据缓冲区是应该比较常用的方式,主要用构建一个内存区用于存储发送的数据和接收的数据;为了更好的利用已有数据缓冲区所以构造一个缓冲池来存放相关数据方便不同连接更好地利用缓冲区,节省不停的构造新的缓冲区所带的损耗问题。
缓冲区
其实构造一个缓冲区非常简单,根据需分本相关大小的byte数组即可;既然是用于存放数据那就自然要实现读和写方法,看一下具体实现
01
public class DataBuffer : IDisposable
02
{
03
public byte[] Data;
04
private int mLength;
05
private int mPostion = 0;
06
internal int mCount = 0;
07
08
public DataBuffer(byte[] data)
09
{
10
Data = data;
11
mLength = data.Length;
12
mPostion = 0;
13
mCount = data.Length;
14
}
15
16
public DataBuffer(int length)
17
{
18
mLength = length;
19
Data = new byte[length];
20
}
21
public void From(Array source, int index, int count)
22
{
23
Array.Copy(source, index, Data, 0, count);
24
mPostion = 0;
25
mCount = count;
26
}
27
public int Write(byte[] data)
28
{
29
return Write(data, 0);
30
}
31
public int Write(byte[] data, int index)
32
{
33
int count = 0;
34
if (mPostion + (data.Length-index) > mLength)
35
{
36
count = mLength - mPostion;
37
}
38
else
39
{
40
count = data.Length - index;
41
}
42
if (count > 0)
43
{
44
Array.Copy(data, index, Data, mPostion, count);
45
46
mPostion += count;
47
mCount += count;
48
}
49
return count;
50
}
51
public ArraySegment Read(int count)
52
{
53
int end = count;
54
if (mPostion + count > mCount)
55
end = mCount - mPostion;
56
57
ArraySegment result= new ArraySegment(Data, mPostion, end);
58
mPostion += end;
59
return result;
60
}
61
public void Seek()
62
{
63
Seek(0);
64
}
65
public void Seek(int postion)
66
{
67
mPostion = 0;
68
}
69
public ArraySegment GetSegment()
70
{
71
return new ArraySegment(Data, 0, mCount);
72
}
73
internal BufferPool Pool
74
{
75
get;
76
set;
77
}
78
public void Dispose()
79
{
80
if (Pool != null)
81
{
82
mPostion = 0;
83
mCount = 0;
84
Pool.Push(this);
85
}
86
}
87
}
为了方便使用,Buffer实现了IDisposable接口,其作为就是当释放的时候把Buffer放回到Pool里.
Buffer提供了两个方法分别是Write和Read用于写和读数据,由于缓冲区有大小限制,所以在写的时候会返回一个成功写入的数量;而read则返回一个ArraySegment用于描述其位置。为什么要这样做呢,其实有些情况一个数据成员会被写入到不同的缓冲区,当读出来的时候就会存要在多个缓冲区中获取。
缓冲池
缓冲池用于发放和回收级冲区,实现一个重用的目的。池的实现并不复杂,封装一个简单的队列操作即可。
01
public class BufferPool : IDisposable
02
{
03
private static List mPools = new List();
04
private static int mIndex = 0;
05
public static void Setup(int pools, int buffers)
06
{
07
Setup(pools, buffers, 2048);
08
}
09
public static void Setup(int pools, int buffers, int bufferlength)
10
{
11