PageRenderTime 42ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/base/Applications/Network/UdpGulp/UdpGulp.cs

#
C# | 195 lines | 152 code | 30 blank | 13 comment | 8 complexity | ed40762c7d2ff04e904850a26125cef2 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="Receive UDP data from a ipAddress, port",
  28. DefaultAction = true)]
  29. internal class Parameters
  30. {
  31. [InputEndpoint("data")]
  32. public readonly TRef<UnicodePipeContract.Exp:READY> Stdin;
  33. [OutputEndpoint("data")]
  34. public readonly TRef<UnicodePipeContract.Imp:READY> Stdout;
  35. [Endpoint]
  36. public readonly TRef<UdpContract.Imp:Start> udpRef;
  37. [LongParameter("t", Mandatory = false, HelpMessage = "Seconds to send packets for", Default = 30)]
  38. internal long seconds;
  39. [StringParameter("a", Mandatory = false, HelpMessage = "Local address to bind to.", Default = "0.0.0.0")]
  40. internal string address;
  41. [LongParameter("port", Mandatory = true, Position = 0, HelpMessage = "port to gulp from")]
  42. internal long port;
  43. reflective internal Parameters();
  44. internal int AppMain()
  45. {
  46. return UdpGulp.AppMain(this);
  47. }
  48. }
  49. public class UdpGulp
  50. {
  51. private const int FixedHeaderBytes = 42; // Ether + IP + UDP
  52. private static void
  53. ReceivePackets(
  54. UdpConnectionContract.Imp:ReadyState! udpConn,
  55. long totalSeconds
  56. )
  57. {
  58. int bytesThisRound = 0;
  59. int packetsThisRound = 0;
  60. DateTime now = DateTime.Now;
  61. DateTime epochEnd = now + TimeSpan.FromSeconds(1);
  62. DateTime epochStart = now;
  63. while (--totalSeconds >= 0) {
  64. while (now < epochEnd) {
  65. udpConn.SendPollRead((epochEnd - now).Milliseconds);
  66. switch receive {
  67. case udpConn.NoData() :
  68. // No data to read. This doesn't
  69. // necessarily mean the connection
  70. // is closed.
  71. Thread.Yield();
  72. break;
  73. case udpConn.Data(uint addr, ushort port2, byte[]! in ExHeap data):
  74. bytesThisRound += data.Length + FixedHeaderBytes;
  75. packetsThisRound++;
  76. delete data;
  77. break;
  78. case udpConn.ChannelClosed():
  79. throw new Exception("udpConn channel closed");
  80. }
  81. now = DateTime.Now;
  82. }
  83. TimeSpan delta = now - epochStart;
  84. string msg = String.Format(
  85. "Duration(s) {0:f2} rate {1:e3} bps, {2:e3} bytes/sec, {3:e3} pps",
  86. delta.TotalSeconds,
  87. 8.0 * bytesThisRound / delta.TotalSeconds,
  88. 8.0 * bytesThisRound / delta.TotalSeconds,
  89. 1.0 * packetsThisRound / delta.TotalSeconds
  90. );
  91. Console.WriteLine(msg);
  92. DebugStub.WriteLine(msg);
  93. bytesThisRound = 0;
  94. packetsThisRound = 0;
  95. epochStart = DateTime.Now;
  96. epochEnd = epochStart + TimeSpan.FromSeconds(1);
  97. }
  98. }
  99. public static int
  100. Gulp([Claims] UdpConnectionContract.Imp:ReadyState! udpConn,
  101. IPv4 address,
  102. ushort port,
  103. long totalSeconds)
  104. {
  105. Console.WriteLine("UdpGulp({0}, {1})", address, port);
  106. try {
  107. // Bind local endpoint
  108. udpConn.SendBindLocalEndPoint((uint)address, port);
  109. switch receive {
  110. case udpConn.OK() :
  111. // success;
  112. Console.WriteLine("Connected");
  113. break;
  114. case udpConn.InvalidEndPoint(ip, rejectedPort) :
  115. throw new Exception("udpConn address and port rejected");
  116. case udpConn.ChannelClosed() :
  117. throw new Exception("udpConn channel closed");
  118. }
  119. ReceivePackets(udpConn, totalSeconds);
  120. Console.WriteLine("Closing connection");
  121. udpConn.SendClose();
  122. }
  123. catch (Exception e) {
  124. Console.WriteLine("Unexpected exception: {0}", e);
  125. }
  126. finally {
  127. delete udpConn;
  128. }
  129. return 0;
  130. }
  131. internal static int AppMain(Parameters! config)
  132. {
  133. IPv4 host;
  134. try {
  135. host = IPv4.Parse(config.address);
  136. }
  137. catch (FormatException e) {
  138. Console.WriteLine("{0}: {1}", e, config.address);
  139. return -1;
  140. }
  141. if (config.port > 0xffff || config.port < 0) {
  142. Console.WriteLine("Port number out of range: {0}",
  143. config.port);
  144. return -1;
  145. }
  146. ushort port = (ushort) config.port;
  147. UdpContract.Imp udpConn = ((!)config.udpRef).Acquire();
  148. if (udpConn == null) {
  149. Console.WriteLine("Could not initialize TCP endpoint.");
  150. return 1;
  151. }
  152. Console.WriteLine("Waiting for ready");
  153. udpConn.RecvReady();
  154. UdpConnectionContract.Imp! connImp;
  155. UdpConnectionContract.Exp! connExp;
  156. UdpConnectionContract.NewChannel(out connImp, out connExp);
  157. Console.WriteLine("Creating session");
  158. udpConn.SendCreateUdpSession(connExp);
  159. connImp.RecvReady();
  160. delete udpConn;
  161. Console.WriteLine("Ready");
  162. return Gulp(connImp, host, port, config.seconds);
  163. }
  164. } // end class UdpGulp
  165. }