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 Hashtable splitMsg(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 Hashtable h=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 Hashtable ms=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 Hashtable splitMsg(string msg)
80 {
81 return MsgSlice.splitMsg(System.Text.ASCIIEncoding.UTF8.GetBytes(msg));
82 }
83
84 //对分片数据进行重组
85 public static byte[] uniteMsg(Hashtable h)
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 static void Main(string[] args)
174 {
175 System.Collections.Hashtable hashtable=new Hashtable();
176
177 string a="--0123456789我-的-地-盘-我-作-猪--";
178 //byte[] b=ASCIIEncoding.UTF8.GetBytes(a);
179 Hashtable ms=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 为解决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 Hashtable splitMsg(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 Hashtable h=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 Hashtable ms=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 Hashtable splitMsg(string msg)
80 {
81 return MsgSlice.splitMsg(System.Text.ASCIIEncoding.UTF8.GetBytes(msg));
82 }
83
84 //对分片数据进行重组
85 public static byte[] uniteMsg(Hashtable h)
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 static void Main(string[] args)
174 {
175 System.Collections.Hashtable hashtable=new Hashtable();
176
177 string a="--0123456789我-的-地-盘-我-作-猪--";
178 //byte[] b=ASCIIEncoding.UTF8.GetBytes(a);
179 Hashtable ms=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