PageRenderTime 41ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/base/Applications/Network/UdpBlast/UdpBlast.cs

#
C# | 261 lines | 202 code | 45 blank | 14 comment | 14 complexity | bf6817cb001ae01e1d8fe8776300cdfc MD5 | raw file
  1. ////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Microsoft Research Singularity
  4. //
  5. // Copyright (c) Microsoft Corporation. All rights reserved.
  6. //
  7. // Note: Simple Singularity test program.
  8. //
  9. using System;
  10. using System.Diagnostics;
  11. using System.Net.IP;
  12. using System.Threading;
  13. using Microsoft.Singularity;
  14. using Microsoft.SingSharp;
  15. using Microsoft.Singularity.Channels;
  16. using Microsoft.Singularity.Directory;
  17. using NetStack.Contracts;
  18. using NetStack.Channels.Public;
  19. using Microsoft.Contracts;
  20. using Microsoft.SingSharp.Reflection;
  21. using Microsoft.Singularity.Applications;
  22. using Microsoft.Singularity.Io;
  23. using Microsoft.Singularity.Configuration;
  24. [assembly: Transform(typeof(ApplicationResourceTransform))]
  25. namespace Microsoft.Singularity.Applications.Network
  26. {
  27. [ConsoleCategory(HelpMessage="Send UDP data to and ipAddress and port",
  28. DefaultAction=true)]
  29. internal class Parameters {
  30. [InputEndpoint("data")]
  31. public readonly TRef<UnicodePipeContract.Exp:READY> Stdin;
  32. [OutputEndpoint("data")]
  33. public readonly TRef<UnicodePipeContract.Imp:READY> Stdout;
  34. [Endpoint]
  35. public readonly TRef<UdpContract.Imp:Start> udpRef;
  36. [LongParameter("p", Mandatory=false, HelpMessage="Packet size (bytes)", Default = 1500)]
  37. internal long packetBytes;
  38. [LongParameter("r", Mandatory=false, HelpMessage="Transmission rate in bits per second", Default = 64000)]
  39. internal long bitsPerSecond;
  40. [LongParameter("t", Mandatory=false, HelpMessage="Seconds to send packets for", Default = 30)]
  41. internal long seconds;
  42. [BoolParameter("v", Mandatory=false, HelpMessage="Verbose output", Default = true)]
  43. internal bool verbose;
  44. [StringParameter("Address", Mandatory=true, Position=0, HelpMessage="Destination IP Address")]
  45. internal string address;
  46. [LongParameter("port", Mandatory=true, Position=1, HelpMessage="Destination UDP port")]
  47. internal long port;
  48. reflective internal Parameters();
  49. internal int AppMain() {
  50. return UdpBlast.AppMain(this);
  51. }
  52. }
  53. public class UdpBlast
  54. {
  55. private const uint FixedHeaderBytes = 42; // Ether + IP + UDP
  56. private static bool verbose;
  57. public static void VerboseWriteLine(string format,
  58. params Object [] args)
  59. {
  60. string msg = String.Format(format, args);
  61. DebugStub.WriteLine(msg);
  62. if (verbose) {
  63. Console.WriteLine(format, args);
  64. }
  65. }
  66. private static void
  67. SendPackets(
  68. UdpConnectionContract.Imp:ReadyState! udpConn,
  69. long bitsPerSecond,
  70. uint bytesPerPacket,
  71. long durationSeconds
  72. )
  73. {
  74. DateTime startTime = DateTime.Now;
  75. DateTime endTime = (startTime +
  76. TimeSpan.FromSeconds(durationSeconds));
  77. DateTime secondStart = startTime;
  78. DateTime secondEnd = startTime + TimeSpan.FromSeconds(1);
  79. DateTime now = startTime;
  80. uint second = 0;
  81. long bitsThisSecond = 0;
  82. long totalBits = 0;
  83. int totalPackets = 0;
  84. VerboseWriteLine("UdpBlast: {0} bytesPerPacket, Limiting transfer to {1} bitsPerSecond, for {2} seconds",
  85. bytesPerPacket, bitsPerSecond, durationSeconds);
  86. while (now < endTime) {
  87. int pps = 0;
  88. while (now < secondEnd && bitsThisSecond < bitsPerSecond) {
  89. // XXX: Just bursting packets out for
  90. // now rather than pacing them,
  91. // interested mainly in saturation case.
  92. byte[] in ExHeap pkt;
  93. uint pktSize;
  94. if ((long)bytesPerPacket * 8 < bitsPerSecond - bitsThisSecond) {
  95. pktSize = bytesPerPacket;
  96. }
  97. else {
  98. // Send a final runt packet for this cycle to keep us under
  99. // the agreed total bits per second rate.
  100. pktSize = (uint)((bitsPerSecond - bitsThisSecond) / 8);
  101. if (pktSize <= FixedHeaderBytes) {
  102. pktSize = FixedHeaderBytes + 1;
  103. }
  104. }
  105. pkt = new [ExHeap] byte [pktSize - FixedHeaderBytes];
  106. udpConn.SendWrite(pkt);
  107. udpConn.RecvOK();
  108. bitsThisSecond += pktSize * 8;
  109. now = DateTime.Now;
  110. pps++;
  111. totalPackets++;
  112. }
  113. while (now < secondEnd) {
  114. Thread.Sleep(0);
  115. now = DateTime.Now;
  116. }
  117. TimeSpan tau = secondEnd - secondStart;
  118. long bytesPerSecond = (bitsThisSecond / tau.TotalSeconds) / 8;
  119. VerboseWriteLine(
  120. "Round {0} duration(secs) {1:f2} rate (pps) {2} rate (bps) {3:e3}, bytes/sec {4:e3}",
  121. second, tau.TotalSeconds,
  122. pps,
  123. bitsThisSecond / tau.TotalSeconds,
  124. bytesPerSecond);
  125. second++;
  126. totalBits += bitsThisSecond;
  127. bitsThisSecond = 0;
  128. secondStart = now;
  129. secondEnd = now + TimeSpan.FromSeconds(1);
  130. }
  131. Console.WriteLine(
  132. "Average rate: packets/sec {0}, bits/sec {1:e3}, bytes/sec {2:e3}",
  133. totalPackets / (now - startTime).TotalSeconds,
  134. totalBits / (now - startTime).TotalSeconds,
  135. (totalBits / (now - startTime).TotalSeconds) / 8
  136. );
  137. }
  138. public static int
  139. Blast(
  140. [Claims] UdpConnectionContract.Imp:ReadyState! udpConn,
  141. IPv4 address,
  142. ushort port,
  143. long bitsPerSecond,
  144. long bytesPerPacket,
  145. long durationSeconds
  146. )
  147. {
  148. Console.WriteLine("UdpBlast({0}, {1})", address, port);
  149. try {
  150. udpConn.SendConnectWithAnyLocalEndPoint((uint)address, port);
  151. switch receive {
  152. case udpConn.OK() :
  153. // success;
  154. Console.WriteLine("Connected");
  155. break;
  156. case udpConn.InvalidEndPoint(ip, rejectedPort) :
  157. throw new Exception("udpConn address and port rejected");
  158. case udpConn.ChannelClosed() :
  159. throw new Exception("udpConn channel closed");
  160. }
  161. SendPackets(udpConn,
  162. bitsPerSecond,
  163. (uint)bytesPerPacket,
  164. durationSeconds);
  165. Console.WriteLine("Closing connection");
  166. udpConn.SendClose();
  167. }
  168. catch (Exception e) {
  169. Console.WriteLine("Unexpected exception: {0}", e);
  170. }
  171. finally {
  172. delete udpConn;
  173. }
  174. return 0;
  175. }
  176. internal static int AppMain(Parameters! config)
  177. {
  178. IPv4 host;
  179. try {
  180. host = IPv4.Parse(config.address);
  181. }
  182. catch (FormatException e) {
  183. Console.WriteLine("{0}: {1}", e, config.address);
  184. return -1;
  185. }
  186. if (config.port > 65536 || config.port < 0) {
  187. Console.WriteLine("Port number out of range: {0}", config.port);
  188. return -1;
  189. }
  190. ushort port = (ushort) config.port;
  191. if ((uint)config.packetBytes < FixedHeaderBytes) {
  192. Console.WriteLine("Packet size needs to be larger than fixed header size ({0} bytes)", FixedHeaderBytes);
  193. return -1;
  194. }
  195. UdpBlast.verbose = config.verbose;
  196. UdpContract.Imp udpConn = ((!)config.udpRef).Acquire();
  197. if (udpConn == null) {
  198. Console.WriteLine("Could not initialize TCP endpoint.");
  199. return 1;
  200. }
  201. udpConn.RecvReady();
  202. UdpConnectionContract.Imp! connImp;
  203. UdpConnectionContract.Exp! connExp;
  204. UdpConnectionContract.NewChannel(out connImp, out connExp);
  205. udpConn.SendCreateUdpSession(connExp);
  206. connImp.RecvReady();
  207. delete udpConn;
  208. return Blast(connImp,
  209. host, port,
  210. config.bitsPerSecond,
  211. config.packetBytes,
  212. config.seconds
  213. );
  214. }
  215. } // end class UdpBlast
  216. }