TinyMind
.net.cn
首页
资讯
文章
注册
登录
C#滑动窗口算法实现UDP流量控制(一)
chen eric
关注文章
TinyMind专栏频道
Code
1
为解决UDP传输中的可靠性和流量控制,参照TCP协议里面的滑动窗口协议写了一个流量控制的东东。还不完善,而且传输速度也不理想(单线程时外网速度才100多K
/
秒)。
2
3
接收端目前还没做窗口控制,因为感觉接收端做不做都无所谓。。
^
_
^
4
5
using
System;
6
using
System.Text;
7
using
System.Collections;
8
9
namespace
scutnetTalkClient
10
{
11
///
<summary>
12
///
消息分片类,用于对消息进行封包、解包。对每个数据拆分为定长(最后一个可能小于定长)的数据段,并存在一个以序列编号为key的Hashtable中。
13
///
主要用于对较大的图片信息进行拆包、封包
14
///
</summary>
15
16
[System.Serializable]
17
public
class
MsgSlice
18
{
19
public
static
long
SLICE_MAX_LENGTH
=
1100
;
//
数据片最大长度
20
private
long
sliceId;
//
片唯一编号
21
private
bool
sliceEnd
=
false
;
//
是否最后一片
22
private
long
sliceIndex
=
0
;
//
片在整个消息中的索引
23
private
byte
[]sliceContent;
//
片内容
24
public
bool
isSimple
=
false
;
25
26
public
MsgSlice()
27
{
28
}
29
30
public
MsgSlice(
byte
[]msg,
bool
isEnd,
long
id,
long
index)
31
{
32
if
(msg
==
null
||
msg.Length
==
0
)
33
{
34
return
;
35
}
36
this
.sliceEnd
=
isEnd;
37
this
.sliceContent
=
msg;
38
this
.sliceId
=
id;
39
this
.sliceIndex
=
index;
40
}
41
42
//
对二进制数据进行分片,并返回分片的Hashtable
43
public
static
HashtablesplitMsg(
byte
[]msg)
44
{
45
if
(msg
==
null
||
msg.Length
==
0
)
46
{
47
return
null
;
48
}
49
long
len
=
msg.Length;
50
if
(len
<=
MsgSlice.SLICE_MAX_LENGTH)
51
{
52
Hashtableh
=
new
Hashtable();
53
h.Add((
long
)
0
,
new
MsgSlice(msg,
true
,
1
,(
long
)
0
));
54
return
h;
55
}
56
long
sliceNum
=
1
;
57
if
(len
%
MsgSlice.SLICE_MAX_LENGTH
==
0
)
58
{
59
sliceNum
=
len
/
MsgSlice.SLICE_MAX_LENGTH;
60
}
61
else
62
{
63
sliceNum
=
len
/
MsgSlice.SLICE_MAX_LENGTH
+
1
;
64
}
65
Hashtablems
=
new
Hashtable();
66
long
id
=
1
;
67
long
i
=
0
;
68
for
(;i
<
sliceNum
-
1
;i
++
)
69
{
70
byte
[]tByte
=
MsgSlice.byteCopy(msg,i
*
MsgSlice.SLICE_MAX_LENGTH,MsgSlice.SLICE_MAX_LENGTH);
71
ms.Add(i,
new
MsgSlice(tByte,
false
,id,i));
72
}
73
byte
[]teByte
=
MsgSlice.byteCopy(msg,i
*
MsgSlice.SLICE_MAX_LENGTH,MsgSlice.SLICE_MAX_LENGTH);
74
ms.Add(i,
new
MsgSlice(teByte,
true
,id,i));
75
return
ms;
76
}
77
78
//
对字符串进行分片(重载),并返回分片Hashtable
79
public
static
HashtablesplitMsg(
string
msg)
80
{
81
return
MsgSlice.splitMsg(System.Text.ASCIIEncoding.UTF8.GetBytes(msg));
82
}
83
84
//
对分片数据进行重组
85
public
static
byte
[]uniteMsg(Hashtableh)
86
{
87
byte
[]result
=
null
;
88
for
(
int
i
=
0
;i
<
h.Count;i
++
)
89
{
90
if
(h[(
long
)i]
!=
null
)
91
{
92
result
=
MsgSlice.byteAdd(result,((MsgSlice)h[(
long
)i]).sliceContent);
93
Console.WriteLine(
"
加入数据
"
+
i);
94
}
95
else
96
{
97
Console.WriteLine(
"
忽略空数据
"
+
i);
98
}
99
}
100
return
result;
101
}
102
103
public
static
byte
[]byteAdd(
byte
[]bt1,
byte
[]bt2)
104
{
105
if
(bt1
==
null
)
106
{
107
return
bt2;
108
}
109
if
(bt2
==
null
)
110
{
111
return
bt1;
112
}
113
114
long
len1
=
bt1.Length;
115
long
len2
=
bt2.Length;
116
117
byte
[]result
=
new
byte
[len1
+
len2];
118
bt1.CopyTo(result,
0
);
119
120
for
(
long
i
=
0
;i
<
len2;i
++
)
121
{
122
result[len1
+
i]
=
bt2[i];
123
}
124
return
result;
125
}
126
127
public
static
byte
[]byteCopy(
byte
[]source,
long
index,
long
len)
128
{
129
byte
[]dest;
130
if
(index
<
0
)
131
{
132
return
null
;
133
}
134
long
sLen
=
source.Length;
135
if
(sLen
<
index
+
len)
136
{
137
dest
=
new
byte
[sLen
-
index];
138
}
139
else
140
{
141
dest
=
new
byte
[len];
142
}
143
long
i
=
0
;
144
for
(;i
<
dest.Length;i
++
)
145
{
146
dest[i]
=
source[index
+
i];
147
}
148
return
dest;
149
}
150
151
public
long
getSliceIndex()
152
{
153
return
this
.sliceIndex;
154
}
155
156
public
long
getSliceId()
157
{
158
return
this
.sliceId;
159
}
160
161
public
bool
isEndSlice()
162
{
163
return
this
.sliceEnd;
164
}
165
166
public
byte
[]getSliceContent()
167
{
168
return
this
.sliceContent;
169
}
170
171
/*
172
[STAThread]
173
staticvoidMain(string[]args)
174
{
175
System.Collections.Hashtablehashtable=newHashtable();
176
177
stringa="--0123456789我-的-地-盘-我-作-猪--";
178
//byte[]b=ASCIIEncoding.UTF8.GetBytes(a);
179
Hashtablems=MsgSlice.splitMsg(a);
180
byte[]b=MsgSlice.uniteMsg(ms);
181
Console.WriteLine(System.Text.ASCIIEncoding.UTF8.GetString(b)+a.Length+"=="+b.Length);
182
Console.ReadLine();
183
}
184
*/
185
}
186
}
187
优质内容筛选与推荐
>>
1、VBScript 内置函数
2、shell 变量
3、修改 Spring Boot 默认页面
4、排序算法的稳定性及其汇总
5、iOS 微信支付SDK与微信友盟分享两者同时集成时,出现的问题与解决之路。
赞赏
长按二维码向我转账
受苹果公司新规定影响,微信 iOS 版的赞赏功能被关闭,可通过二维码转账支持公众号。
阅读
好看
已推荐到看一看
你的朋友可以在“发现”-“看一看”看到你认为好看的文章。
取消
推荐
我知道了
已取消,“好看”想法已同步删除
知道了
已推荐到看一看
和朋友分享想法
最多200字,当前共
字
发送
已发送
朋友将在看一看看到
确定
分享你的想法...
取消
分享想法到看一看
确定
最多200字,当前共
字
发送中
网络异常,请稍后重试
知道了
微信扫一扫
关注该公众号
0
│
收藏
│
举报