Code
1 C#滑动窗口算法实现UDP流量控制【原创】(三)2007-01-15 16:27//接收方
2
3 using System;
4 using System.Collections;
5 using System.Net.Sockets;
6 using System.Net;
7 using System.Threading;
8 using System.Text;
9 using seal.common;
10
11 namespace scutnetTalkClient
12 {
13 /// <summary>
14 /// UDPReceiveWindow 的摘要说明。
15 /// </summary>
16 public class UDPReceiveWindow
17 {
18 private Hashtable receiveList=new Hashtable();
19 public UdpClient client=new UdpClient(8080);
20 public SlidingWindow receiveWindow=new SlidingWindow(5);
21
22
23 public UDPReceiveWindow()
24 {
25 }
26
27 public void receiveThread(object o)
28 {
29 IPEndPoint remoteIp=null;
30 while(true)
31 {
32 byte[] buff=client.Receive(ref remoteIp);
33 object pack=FormatterHelper.Deserialize(buff);
34 if(typeof(MsgSlice)==pack.GetType())
35 {
36 MsgSlice ms=(MsgSlice)pack;
37 //Console.WriteLine("接收到数据:"+ms.getSliceIndex());
38 receiveList.Remove(ms.getSliceIndex());
39 receiveList.Add(ms.getSliceIndex(),ms);
40 if(!ms.isSimple)
41 {
42 //一般帧,返回响应信息
43 byte[] actBt=new byte[9];
44 long index=ms.getSliceIndex();
45 byte[] hBt=new byte[1];
46 byte[] iBt=BitConverter.GetBytes(index);
47 hBt[0]=UDPSlidingWindow.MSG_SLICE_COMPLETE;
48 actBt=MsgSlice.byteAdd(hBt,iBt);
49 //remoteIp.Port=8211;
50 client.Send(actBt,actBt.Length,remoteIp);
51 //Console.WriteLine("回应接收到片信息:"+index);
52 if(ms.isEndSlice())
53 {//接收到最后帧
54 if(ms.getSliceIndex()+1==(long)receiveList.Count)
55 {//全部接收完毕,则发送“接收完毕”指令
56 actBt=new byte[1];
57 actBt[0]=UDPSlidingWindow.MSG_COMPLETE;
58 client.Send(actBt,1,remoteIp);
59 byte[] msgBt=MsgSlice.uniteMsg(receiveList);
60 Console.WriteLine("所有数据片接收完毕。");
61 Console.WriteLine("接收到的数据重组后为:"+System.Text.ASCIIEncoding.UTF8.GetString(msgBt));
62 receiveList.Clear();
63 }
64 else
65 {//中间有缺包,遍历最后接收窗口,找到缺包,并请求重发。(可有可无?)
66 Console.WriteLine((ms.getSliceIndex()+1)+"=="+receiveList.Count+"数据缺包,待处理。。。。。");
67 }
68 }
69 }
70 }
71 //Thread.Sleep(50);
72 }
73 }
74 /*
75 [STAThread]
76 static void Main(string[] args)
77 {
78 UDPReceiveWindow urw=new UDPReceiveWindow();
79 System.Threading.ThreadPool.QueueUserWorkItem(new WaitCallback(urw.receiveThread));
80 Console.ReadLine();
81 }
82 //*/
83 }
84 }
85
86
87 后记:
88
89 UDP数据在不同网段间传输推荐数据包大小推荐为1024字节左右,超过路由的最大传输单元时,路由需拆分重组,影响传输速度。本程序中采用单包大小1500字节时在外网传输就不行了,可能是由于本地路由的关系。局域网中可以修改相应参数,测试时单包大小改为64K,重发延时改为半秒,速度可以达到1.5M/秒。另:本例中用到的序列化和反序列化函数封装在dll中。可自行编写。
90
91
92
1 C#滑动窗口算法实现UDP流量控制【原创】(三)2007-01-15 16:27//接收方
2
3 using System;
4 using System.Collections;
5 using System.Net.Sockets;
6 using System.Net;
7 using System.Threading;
8 using System.Text;
9 using seal.common;
10
11 namespace scutnetTalkClient
12 {
13 /// <summary>
14 /// UDPReceiveWindow 的摘要说明。
15 /// </summary>
16 public class UDPReceiveWindow
17 {
18 private Hashtable receiveList=new Hashtable();
19 public UdpClient client=new UdpClient(8080);
20 public SlidingWindow receiveWindow=new SlidingWindow(5);
21
22
23 public UDPReceiveWindow()
24 {
25 }
26
27 public void receiveThread(object o)
28 {
29 IPEndPoint remoteIp=null;
30 while(true)
31 {
32 byte[] buff=client.Receive(ref remoteIp);
33 object pack=FormatterHelper.Deserialize(buff);
34 if(typeof(MsgSlice)==pack.GetType())
35 {
36 MsgSlice ms=(MsgSlice)pack;
37 //Console.WriteLine("接收到数据:"+ms.getSliceIndex());
38 receiveList.Remove(ms.getSliceIndex());
39 receiveList.Add(ms.getSliceIndex(),ms);
40 if(!ms.isSimple)
41 {
42 //一般帧,返回响应信息
43 byte[] actBt=new byte[9];
44 long index=ms.getSliceIndex();
45 byte[] hBt=new byte[1];
46 byte[] iBt=BitConverter.GetBytes(index);
47 hBt[0]=UDPSlidingWindow.MSG_SLICE_COMPLETE;
48 actBt=MsgSlice.byteAdd(hBt,iBt);
49 //remoteIp.Port=8211;
50 client.Send(actBt,actBt.Length,remoteIp);
51 //Console.WriteLine("回应接收到片信息:"+index);
52 if(ms.isEndSlice())
53 {//接收到最后帧
54 if(ms.getSliceIndex()+1==(long)receiveList.Count)
55 {//全部接收完毕,则发送“接收完毕”指令
56 actBt=new byte[1];
57 actBt[0]=UDPSlidingWindow.MSG_COMPLETE;
58 client.Send(actBt,1,remoteIp);
59 byte[] msgBt=MsgSlice.uniteMsg(receiveList);
60 Console.WriteLine("所有数据片接收完毕。");
61 Console.WriteLine("接收到的数据重组后为:"+System.Text.ASCIIEncoding.UTF8.GetString(msgBt));
62 receiveList.Clear();
63 }
64 else
65 {//中间有缺包,遍历最后接收窗口,找到缺包,并请求重发。(可有可无?)
66 Console.WriteLine((ms.getSliceIndex()+1)+"=="+receiveList.Count+"数据缺包,待处理。。。。。");
67 }
68 }
69 }
70 }
71 //Thread.Sleep(50);
72 }
73 }
74 /*
75 [STAThread]
76 static void Main(string[] args)
77 {
78 UDPReceiveWindow urw=new UDPReceiveWindow();
79 System.Threading.ThreadPool.QueueUserWorkItem(new WaitCallback(urw.receiveThread));
80 Console.ReadLine();
81 }
82 //*/
83 }
84 }
85
86
87 后记:
88
89 UDP数据在不同网段间传输推荐数据包大小推荐为1024字节左右,超过路由的最大传输单元时,路由需拆分重组,影响传输速度。本程序中采用单包大小1500字节时在外网传输就不行了,可能是由于本地路由的关系。局域网中可以修改相应参数,测试时单包大小改为64K,重发延时改为半秒,速度可以达到1.5M/秒。另:本例中用到的序列化和反序列化函数封装在dll中。可自行编写。
90
91
92