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

280 lines
9.2 KiB
C#
Raw Permalink Normal View History

2008-03-05 09:52:00 -05:00
////////////////////////////////////////////////////////////////////////////////
//
// Microsoft Research Singularity
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// Note: Simple Singularity test program.
//
using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Collections;
#if SINGULARITY
using Microsoft.Contracts;
using System.IO;
using System.Runtime.InteropServices;
using Microsoft.SingSharp;
using Microsoft.Singularity;
using Microsoft.Singularity.Channels;
using NetStack.Contracts;
using NetStack.Channels.Public;
using Microsoft.Contracts;
using Microsoft.SingSharp.Reflection;
using Microsoft.Singularity.Applications;
using Microsoft.Singularity.Io;
using Microsoft.Singularity.Configuration;
[assembly: Transform(typeof(ApplicationResourceTransform))]
#endif
namespace Microsoft.Singularity.Applications.Network
{
#if SINGULARITY
[ConsoleCategory(HelpMessage="BlastServer TCP data to a ipAddress, port", DefaultAction=true)]
internal class Parameters {
[InputEndpoint("data")]
public readonly TRef<UnicodePipeContract.Exp:READY> Stdin;
[OutputEndpoint("data")]
public readonly TRef<UnicodePipeContract.Imp:READY> Stdout;
[Endpoint]
public readonly TRef<TcpContract.Imp:Start> tcpRef;
[LongParameter( "port", Mandatory=true, Position=0, HelpMessage="port to gulp from ")]
internal long port;
2008-11-17 18:29:00 -05:00
[LongParameter( "numBytes", Mandatory=false, Position=1, HelpMessage="Total bytes to send", Default = 10000)]
2008-03-05 09:52:00 -05:00
internal long numBytes;
2008-11-17 18:29:00 -05:00
[LongParameter( "chunkSize", Mandatory=false, Position=2, HelpMessage="Chunks size to send", Default = 256)]
2008-03-05 09:52:00 -05:00
internal long chunkSize;
reflective internal Parameters();
internal int AppMain() {
return BlastServer.AppMain(this);
}
}
#endif
public class BlastServer
{
///////////////////////////////////////////////////////////////////////
// Constants
private const int WorkerThreads = 32;
private const int MaxWorkItems = 32 * WorkerThreads;
private const string RepeatPattern = "Here is a repeating string of text that serves as content. ";
///////////////////////////////////////////////////////////////////////
// class variables
ushort port;
uint numBytes;
uint chunkSize;
byte[] chunkBuffer;
ThreadPool threadPool;
private void DispatchRequest(object dispatchObject)
{
Console.WriteLine(dispatchObject as string);
Console.WriteLine("We should Never get here");
#if SINGULARITY
DebugStub.Break();
#endif
}
private void test (object dispatchObject)
{
Console.Write(dispatchObject as string);
}
private void Blaster (object sock)
{
Socket socket = sock as Socket;
#if SINGULARITY
assert socket != null;
#endif
int bytesSent = 0;
int iterations =0;
2008-11-17 18:29:00 -05:00
Console.WriteLine("Got connection...");
2008-03-05 09:52:00 -05:00
uint bytesLeft = numBytes, patternLength = (uint)RepeatPattern.Length;
try {
while (bytesLeft > 0) {
uint thisPass = chunkSize < bytesLeft ? chunkSize : bytesLeft;
if (thisPass == chunkSize) {
socket.Send(chunkBuffer);
}
else {
byte[] thisPassBuffer = new byte[thisPass];
for (uint i = 0; i < thisPass; i++) {
thisPassBuffer [(int)i] = (byte)RepeatPattern[(int)i % (int)patternLength];
}
socket.Send(thisPassBuffer);
}
bytesLeft -= thisPass;
bytesSent += (int) thisPass;
iterations++;
2008-11-17 18:29:00 -05:00
Console.Write(".");
2008-03-05 09:52:00 -05:00
}
2008-11-17 18:29:00 -05:00
}
catch (ArgumentNullException ae) {
2008-03-05 09:52:00 -05:00
Console.WriteLine("ArgumentNullException : {0}", ae.ToString());
2008-11-17 18:29:00 -05:00
}
catch (SocketException se) {
2008-03-05 09:52:00 -05:00
Console.WriteLine("SocketException : {0}", se.ToString());
2008-11-17 18:29:00 -05:00
}
catch (Exception e) {
2008-03-05 09:52:00 -05:00
Console.WriteLine("Unexpected exception : {0}", e.ToString());
}
2008-11-17 18:29:00 -05:00
Console.WriteLine("\nSent {0} bytes in {1} iterations",bytesSent,iterations);
2008-03-05 09:52:00 -05:00
socket.Shutdown(SocketShutdown.Both);
socket.Close();
Thread.Sleep(2);
}
private void Listen() {
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socket.Bind(new IPEndPoint(IPAddress.Any, (int)this.port));
socket.Listen((int)SocketOptionName.MaxConnections);
while (true) {
Socket s = socket.Accept();
threadPool.QueueUserWorkItem(new ThreadPool.WorkCallback(Blaster), s);
}
}
#if SINGULARITY
[NotDelayed]
#endif
public BlastServer (ushort port, uint numBytes, uint chunkSize)
{
this.port = port;
this.numBytes = numBytes;
this.chunkSize = chunkSize;
chunkBuffer = new byte[chunkSize];
for (uint i = 0; i < chunkSize; i++) {
chunkBuffer [(int)i] = (byte)RepeatPattern[(int)i % (int)RepeatPattern.Length];
}
Console.WriteLine("BlastServer listening on port {0} for {1} bytes in {2}-byte chunks",
port, numBytes, chunkSize);
threadPool = new ThreadPool(
WorkerThreads, MaxWorkItems,
new ThreadPool.WorkCallback(DispatchRequest)
);
#if blee
2008-11-17 18:29:00 -05:00
for (int i = 0; i < 50; i++) {
for (int j = 0; j < 40; j++) {
2008-03-05 09:52:00 -05:00
bool isFull = threadPool.QueueUserWorkItem(new ThreadPool.WorkCallback(test), ".");
while (isFull) {
Thread.Sleep(2);
isFull = threadPool.QueueUserWorkItem(new ThreadPool.WorkCallback(test), "yes\n");
}
}
Thread.Sleep(300);
}
#endif
}
public static void Usage()
{
Console.WriteLine("blastserver <port> <numBytes> <chunkSize>");
}
public void Shutdown()
{
threadPool.Shutdown();
}
#if SINGULARITY
internal static int AppMain(Parameters! config)
{
2008-11-17 18:29:00 -05:00
if (config.port > 65536 || config.port < 0) {
2008-03-05 09:52:00 -05:00
Console.WriteLine("Port number out of range: {0}", config.port);
return -1;
}
ushort port = (ushort) config.port;
uint numBytes = (uint) config.numBytes;
uint chunkSize = (uint) config.chunkSize;
BlastServer bs = new BlastServer( port, numBytes, chunkSize);
bs.Listen();
bs.Shutdown();
return 0;
}
#else
public static int Main(string[] /*!*/ args)
{
int start = -1;
2008-11-17 18:29:00 -05:00
if (args.Length < 4 + start) {
2008-03-05 09:52:00 -05:00
Usage();
return 1;
}
ushort port;
try {
port = UInt16.Parse(args[1+start]);
}
catch (FormatException) {
Console.WriteLine("Malformed port number: {0}", args[1+start]);
return -1;
}
catch (OverflowException) {
Console.WriteLine("Port number out of range: {0}", args[1+start]);
return -1;
}
uint numBytes;
try {
numBytes = UInt32.Parse(args[2+start]);
}
catch (FormatException) {
Console.WriteLine("Malformed number of bytes: {0}", args[2+start]);
return -1;
}
catch (OverflowException) {
Console.WriteLine("Byte count out of range: {0}", args[2+start]);
return -1;
}
uint chunkSize;
try {
chunkSize = UInt32.Parse(args[3+start]);
}
catch (FormatException) {
Console.WriteLine("Malformed chunk size: {0}", args[3+start]);
return -1;
}
catch (OverflowException) {
Console.WriteLine("Chunk size out of range: {0}", args[3+start]);
return -1;
}
BlastServer bs = new BlastServer( port, numBytes, chunkSize);
bs.Listen();
bs.Shutdown();
return 0;
}
#endif
} // end class TcpBlast
}