您的位置:首页 > 编程语言 > C#

C#滑动窗口算法实现UDP流量控制(二)

2008-12-19 23:10 441 查看
Code

1 //主类:模拟滑动窗口协议

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

12 namespace scutnetTalkClient

13 {

14 /// <summary>

15 /// UDPSlidingWindow udp滑动窗口类。

16 /// </summary>

17 public class UDPSlidingWindow

18 {

19 public static byte MSG_COMPLETE=0x01;//队列数据发送完毕

20 public static byte MSG_SLICE_SENDED=0x03;//片发送状态

21 public static byte MSG_SLICE_COMPLETE=0x04;//片完毕应答

22 public static long MAX_WAIT_TIME=3000;//窗口最大等待时间

23 public static int MAX_RETRY_TIME=5;//窗口最大重发次数

24 private byte ret;

25 private int retryTime=0;

26 private SlidingWindow sendWindow=new SlidingWindow(5);

27 private Hashtable sendList=new Hashtable();

28 private Hashtable state=new Hashtable();

29 public static UdpClient sendClient=new UdpClient(8211);

30 public string msg;

31 public System.Net.IPEndPoint target;

32

33 public UDPSlidingWindow()

34 {

35 //

36 // TODO: 在此处添加构造函数逻辑

37 //

38 }

39

40 public void sendThread(object o)

41 {

42 byte[] sendBuffer=System.Text.ASCIIEncoding.UTF8.GetBytes(msg);

43 Console.WriteLine("发送开始时间:"+DateTime.Now);

44 Console.WriteLine("待发数据长度:"+sendBuffer.Length/1024+"K Byte】");

45

46 sendList=MsgSlice.splitMsg(sendBuffer);

47 //Console.WriteLine("准备发送数据:"+sendList.Count+"片");

48 while(ret!=UDPSlidingWindow.MSG_COMPLETE)

49 {

50 if(((DateTime.Now)>sendWindow.lastActiveTime.AddMilliseconds(UDPSlidingWindow.MAX_WAIT_TIME)))

51 {//窗口停留超时,则重发落在窗口内未标志为“已接收”的所有包

52 if(retryTime>=UDPSlidingWindow.MAX_RETRY_TIME)

53 {//重发次数超过设定值,退出。

54 Console.WriteLine("重发次数超过"+UDPSlidingWindow.MAX_RETRY_TIME+",发送数据失败!请检查网络是否正常连接。");

55 return;

56 }

57 Console.WriteLine((DateTime.Now).ToString()+"===>"+sendWindow.lastActiveTime.AddMilliseconds(UDPSlidingWindow.MAX_WAIT_TIME));

58 for(long i=sendWindow.getWindowHead()-sendWindow.getUsedSize();i<sendWindow.getWindowHead();i++)

59 {

60 MsgSlice tmpMs=(MsgSlice)sendList[i];

61 if(tmpMs!=null&&(state[i]==null||(byte)state[i]!=UDPSlidingWindow.MSG_SLICE_COMPLETE))

62 {

63 Console.WriteLine("重新发送数据:"+i);

64 byte[] tmpBt=FormatterHelper.Serialize(tmpMs);

65 sendClient.Send(tmpBt,tmpBt.Length,target);

66 state.Remove(i);

67 state.Add(i,UDPSlidingWindow.MSG_SLICE_SENDED);//将窗口内新发送包加入到等待回应队列

68 }

69 }

70 retryTime++;

71 sendWindow.lastActiveTime=DateTime.Now;

72 }

73 while((state[(long)(sendWindow.getWindowHead()-sendWindow.getUsedSize())]!=null&&(byte)state[(long)(sendWindow.getWindowHead()-sendWindow.getUsedSize())]==MSG_SLICE_COMPLETE||sendWindow.getUsedSize()<sendWindow.getMaxSize())&&sendWindow.getWindowHead()<sendList.Count)

74 {//滑动窗口下标数据已经完成且数据未发完,则发送下一个包,并且窗口前移。

75 retryTime=0;

76 MsgSlice tmpMs=(MsgSlice)sendList[(long)sendWindow.getWindowHead()];

77 //Console.WriteLine("准备发送:"+sendWindow.getWindowHead()+":"+tmpMs.isEndSlice());

78 byte[] tmpBt=FormatterHelper.Serialize(tmpMs);

79 sendClient.Send(tmpBt,tmpBt.Length,target);

80 sendWindow.moveAhead();

81 state.Add(sendWindow.getWindowHead(),UDPSlidingWindow.MSG_SLICE_SENDED);//将窗口内新发送包加入到等待回应队列

82 }

83 //Thread.Sleep(50);

84 }

85 }

86

87

88 public void recieveThread(object o)

89 {

90 while(true)

91 {

92 IPEndPoint remoteIp=new IPEndPoint(IPAddress.Any,0);

93 byte[] act=sendClient.Receive(ref remoteIp);

94 if(act[0]==UDPSlidingWindow.MSG_SLICE_COMPLETE)

95 {//接收到片完成信息

96 long index=BitConverter.ToInt64(act,1);

97 state.Remove(index);

98 state.Add(index,UDPSlidingWindow.MSG_SLICE_COMPLETE);

99 //Console.WriteLine("接收到数据包完成信息:"+index);

100 }

101 else if(act[0]==UDPSlidingWindow.MSG_COMPLETE)

102 {//接收到“数据接收完毕”信息

103 ret=UDPSlidingWindow.MSG_COMPLETE;

104 Console.WriteLine("全部数据成功发送完毕,收工");

105 Console.WriteLine("发送结束时间:"+DateTime.Now);

106 return;

107 }

108 }

109 }

110 //*

111 [STAThread]

112 static void Main(string[] args)

113 {

114 string ip="192.168.0.244";

115 string msg="0--begin--0123456789我-的-地-盘-我-作-猪----0123456789我-的-地-盘-我-作-猪----0123456789我-的-地-盘-我-作-猪----0123456789我-的-地-盘-我-作-猪----0123456789我-的-地-盘-我-作-猪----0123456789我-的-地-盘-我-作-猪----0123456789我-的-地-盘-我-作-猪--end---0";

116 msg+=msg;

117 msg+=msg;

118 msg+=msg;

119 msg+=msg;

120 msg+=msg;

121 msg+=msg;

122 msg+=msg;

123 msg+=msg;

124 msg+=msg;

125 msg+=msg;

126 msg+=msg;

127 msg="[begin]"+msg+"[end]";

128

129 Console.WriteLine("请输入发送目的IP:");

130 ip=Console.ReadLine();

131 ip=ip==""?"192.168.0.244":ip;

132 IPEndPoint target=new IPEndPoint(IPAddress.Parse(ip),8080);

133 while(true)

134 {

135 Console.WriteLine("是否再发送?");

136 if(Console.ReadLine().ToLower()=="y")

137 {

138 UDPSlidingWindow usw=new UDPSlidingWindow();

139 usw.target=target;

140 usw.msg=msg;

141 System.Threading.ThreadPool.QueueUserWorkItem(new WaitCallback(usw.recieveThread));

142 System.Threading.ThreadPool.QueueUserWorkItem(new WaitCallback(usw.sendThread));

143 }

144 }

145 }

146 //*/

147 }

148

149 public class SlidingWindow

150 {

151 private int maxSize;

152 private int usedSize=0;

153 private int windowHead=0;

154 public DateTime beginTime;

155 public DateTime lastActiveTime;

156

157 public SlidingWindow()

158 {

159 beginTime=DateTime.Now;

160 lastActiveTime=beginTime;

161 this.maxSize=5;

162 }

163

164 public SlidingWindow(int m)

165 {

166 beginTime=DateTime.Now;

167 lastActiveTime=beginTime;

168 this.maxSize=m;

169 }

170

171 //窗口向前移动

172 public void moveAhead()

173 {

174 this.windowHead++;

175 if(this.usedSize<this.maxSize)

176 {

177 this.usedSize++;

178 }

179 this.lastActiveTime=DateTime.Now;

180 }

181

182 //发送完毕后窗口回到原位

183 public void resetWindowHead()

184 {

185 this.windowHead=0;

186 }

187

188 public void takeOne()

189 {

190 if(this.usedSize>0)

191 {

192 this.usedSize--;

193 }

194 this.lastActiveTime=DateTime.Now;

195 }

196

197 public int getMaxSize()

198 {

199 return this.maxSize;

200 }

201

202 public int getUsedSize()

203 {

204 return this.usedSize;

205 }

206

207 public int getWindowHead()

208 {

209 return this.windowHead;

210 }

211 }

212 }

213

214

215

216
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: