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

/base/Applications/Network/BlastServer/BlastServer.cs

#
C# | 279 lines | 224 code | 43 blank | 12 comment | 14 complexity | aa44c2d2cc6ffe0f7bbfcc9efdb68edc 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.Net;
  11. using System.Net.Sockets;
  12. using System.Threading;
  13. using System.Collections;
  14. #if SINGULARITY
  15. using Microsoft.Contracts;
  16. using System.IO;
  17. using System.Runtime.InteropServices;
  18. using Microsoft.SingSharp;
  19. using Microsoft.Singularity;
  20. using Microsoft.Singularity.Channels;
  21. using NetStack.Contracts;
  22. using NetStack.Channels.Public;
  23. using Microsoft.Contracts;
  24. using Microsoft.SingSharp.Reflection;
  25. using Microsoft.Singularity.Applications;
  26. using Microsoft.Singularity.Io;
  27. using Microsoft.Singularity.Configuration;
  28. [assembly: Transform(typeof(ApplicationResourceTransform))]
  29. #endif
  30. namespace Microsoft.Singularity.Applications.Network
  31. {
  32. #if SINGULARITY
  33. [ConsoleCategory(HelpMessage="BlastServer TCP data to a ipAddress, port", DefaultAction=true)]
  34. internal class Parameters {
  35. [InputEndpoint("data")]
  36. public readonly TRef<UnicodePipeContract.Exp:READY> Stdin;
  37. [OutputEndpoint("data")]
  38. public readonly TRef<UnicodePipeContract.Imp:READY> Stdout;
  39. [Endpoint]
  40. public readonly TRef<TcpContract.Imp:Start> tcpRef;
  41. [LongParameter( "port", Mandatory=true, Position=0, HelpMessage="port to gulp from ")]
  42. internal long port;
  43. [LongParameter( "numBytes", Mandatory=false, Position=1, HelpMessage="Total bytes to send", Default = 10000)]
  44. internal long numBytes;
  45. [LongParameter( "chunkSize", Mandatory=false, Position=2, HelpMessage="Chunks size to send", Default = 256)]
  46. internal long chunkSize;
  47. reflective internal Parameters();
  48. internal int AppMain() {
  49. return BlastServer.AppMain(this);
  50. }
  51. }
  52. #endif
  53. public class BlastServer
  54. {
  55. ///////////////////////////////////////////////////////////////////////
  56. // Constants
  57. private const int WorkerThreads = 32;
  58. private const int MaxWorkItems = 32 * WorkerThreads;
  59. private const string RepeatPattern = "Here is a repeating string of text that serves as content. ";
  60. ///////////////////////////////////////////////////////////////////////
  61. // class variables
  62. ushort port;
  63. uint numBytes;
  64. uint chunkSize;
  65. byte[] chunkBuffer;
  66. ThreadPool threadPool;
  67. private void DispatchRequest(object dispatchObject)
  68. {
  69. Console.WriteLine(dispatchObject as string);
  70. Console.WriteLine("We should Never get here");
  71. #if SINGULARITY
  72. DebugStub.Break();
  73. #endif
  74. }
  75. private void test (object dispatchObject)
  76. {
  77. Console.Write(dispatchObject as string);
  78. }
  79. private void Blaster (object sock)
  80. {
  81. Socket socket = sock as Socket;
  82. #if SINGULARITY
  83. assert socket != null;
  84. #endif
  85. int bytesSent = 0;
  86. int iterations =0;
  87. Console.WriteLine("Got connection...");
  88. uint bytesLeft = numBytes, patternLength = (uint)RepeatPattern.Length;
  89. try {
  90. while (bytesLeft > 0) {
  91. uint thisPass = chunkSize < bytesLeft ? chunkSize : bytesLeft;
  92. if (thisPass == chunkSize) {
  93. socket.Send(chunkBuffer);
  94. }
  95. else {
  96. byte[] thisPassBuffer = new byte[thisPass];
  97. for (uint i = 0; i < thisPass; i++) {
  98. thisPassBuffer [(int)i] = (byte)RepeatPattern[(int)i % (int)patternLength];
  99. }
  100. socket.Send(thisPassBuffer);
  101. }
  102. bytesLeft -= thisPass;
  103. bytesSent += (int) thisPass;
  104. iterations++;
  105. Console.Write(".");
  106. }
  107. }
  108. catch (ArgumentNullException ae) {
  109. Console.WriteLine("ArgumentNullException : {0}", ae.ToString());
  110. }
  111. catch (SocketException se) {
  112. Console.WriteLine("SocketException : {0}", se.ToString());
  113. }
  114. catch (Exception e) {
  115. Console.WriteLine("Unexpected exception : {0}", e.ToString());
  116. }
  117. Console.WriteLine("\nSent {0} bytes in {1} iterations",bytesSent,iterations);
  118. socket.Shutdown(SocketShutdown.Both);
  119. socket.Close();
  120. Thread.Sleep(2);
  121. }
  122. private void Listen() {
  123. Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  124. socket.Bind(new IPEndPoint(IPAddress.Any, (int)this.port));
  125. socket.Listen((int)SocketOptionName.MaxConnections);
  126. while (true) {
  127. Socket s = socket.Accept();
  128. threadPool.QueueUserWorkItem(new ThreadPool.WorkCallback(Blaster), s);
  129. }
  130. }
  131. #if SINGULARITY
  132. [NotDelayed]
  133. #endif
  134. public BlastServer (ushort port, uint numBytes, uint chunkSize)
  135. {
  136. this.port = port;
  137. this.numBytes = numBytes;
  138. this.chunkSize = chunkSize;
  139. chunkBuffer = new byte[chunkSize];
  140. for (uint i = 0; i < chunkSize; i++) {
  141. chunkBuffer [(int)i] = (byte)RepeatPattern[(int)i % (int)RepeatPattern.Length];
  142. }
  143. Console.WriteLine("BlastServer listening on port {0} for {1} bytes in {2}-byte chunks",
  144. port, numBytes, chunkSize);
  145. threadPool = new ThreadPool(
  146. WorkerThreads, MaxWorkItems,
  147. new ThreadPool.WorkCallback(DispatchRequest)
  148. );
  149. #if blee
  150. for (int i = 0; i < 50; i++) {
  151. for (int j = 0; j < 40; j++) {
  152. bool isFull = threadPool.QueueUserWorkItem(new ThreadPool.WorkCallback(test), ".");
  153. while (isFull) {
  154. Thread.Sleep(2);
  155. isFull = threadPool.QueueUserWorkItem(new ThreadPool.WorkCallback(test), "yes\n");
  156. }
  157. }
  158. Thread.Sleep(300);
  159. }
  160. #endif
  161. }
  162. public static void Usage()
  163. {
  164. Console.WriteLine("blastserver <port> <numBytes> <chunkSize>");
  165. }
  166. public void Shutdown()
  167. {
  168. threadPool.Shutdown();
  169. }
  170. #if SINGULARITY
  171. internal static int AppMain(Parameters! config)
  172. {
  173. if (config.port > 65536 || config.port < 0) {
  174. Console.WriteLine("Port number out of range: {0}", config.port);
  175. return -1;
  176. }
  177. ushort port = (ushort) config.port;
  178. uint numBytes = (uint) config.numBytes;
  179. uint chunkSize = (uint) config.chunkSize;
  180. BlastServer bs = new BlastServer( port, numBytes, chunkSize);
  181. bs.Listen();
  182. bs.Shutdown();
  183. return 0;
  184. }
  185. #else
  186. public static int Main(string[] /*!*/ args)
  187. {
  188. int start = -1;
  189. if (args.Length < 4 + start) {
  190. Usage();
  191. return 1;
  192. }
  193. ushort port;
  194. try {
  195. port = UInt16.Parse(args[1+start]);
  196. }
  197. catch (FormatException) {
  198. Console.WriteLine("Malformed port number: {0}", args[1+start]);
  199. return -1;
  200. }
  201. catch (OverflowException) {
  202. Console.WriteLine("Port number out of range: {0}", args[1+start]);
  203. return -1;
  204. }
  205. uint numBytes;
  206. try {
  207. numBytes = UInt32.Parse(args[2+start]);
  208. }
  209. catch (FormatException) {
  210. Console.WriteLine("Malformed number of bytes: {0}", args[2+start]);
  211. return -1;
  212. }
  213. catch (OverflowException) {
  214. Console.WriteLine("Byte count out of range: {0}", args[2+start]);
  215. return -1;
  216. }
  217. uint chunkSize;
  218. try {
  219. chunkSize = UInt32.Parse(args[3+start]);
  220. }
  221. catch (FormatException) {
  222. Console.WriteLine("Malformed chunk size: {0}", args[3+start]);
  223. return -1;
  224. }
  225. catch (OverflowException) {
  226. Console.WriteLine("Chunk size out of range: {0}", args[3+start]);
  227. return -1;
  228. }
  229. BlastServer bs = new BlastServer( port, numBytes, chunkSize);
  230. bs.Listen();
  231. bs.Shutdown();
  232. return 0;
  233. }
  234. #endif
  235. } // end class TcpBlast
  236. }