187 lines
6.1 KiB
Plaintext
187 lines
6.1 KiB
Plaintext
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// Microsoft Research Singularity
|
||
|
//
|
||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||
|
//
|
||
|
// File: TcpBlast.cs
|
||
|
//
|
||
|
// Note: Simple Singularity test program.
|
||
|
//
|
||
|
using System;
|
||
|
using System.Diagnostics;
|
||
|
using System.Net.IP;
|
||
|
|
||
|
using Microsoft.SingSharp;
|
||
|
using Microsoft.Singularity;
|
||
|
using Microsoft.Singularity.Channels;
|
||
|
using Microsoft.Singularity.Directory;
|
||
|
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))]
|
||
|
|
||
|
namespace Microsoft.Singularity.Applications.Network
|
||
|
{
|
||
|
[ConsoleCategory(HelpMessage="Blast 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;
|
||
|
|
||
|
[StringParameter( "address", Mandatory=true, Position=0, HelpMessage="IP Address to receive from")]
|
||
|
internal string address;
|
||
|
|
||
|
|
||
|
[LongParameter( "port", Mandatory=true, Position=1, HelpMessage="port to gulp from ")]
|
||
|
internal long port;
|
||
|
|
||
|
|
||
|
[LongParameter( "numBytes", Mandatory=true, Position=2, HelpMessage="Total bytes to send")]
|
||
|
internal long numBytes;
|
||
|
|
||
|
|
||
|
[LongParameter( "chunkSize", Mandatory=true, Position=3, HelpMessage="Chunks size to send")]
|
||
|
internal long chunkSize;
|
||
|
|
||
|
reflective internal Parameters();
|
||
|
|
||
|
internal int AppMain() {
|
||
|
return TcpBlast.AppMain(this);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public class TcpBlast
|
||
|
{
|
||
|
private const string RepeatPattern = "Here is a repeating string of text that serves as content. ";
|
||
|
|
||
|
public static int Blast([Claims] TcpConnectionContract.Imp:ReadyState! tcpConn,
|
||
|
IPv4 address, ushort port, uint numBytes, uint chunkSize)
|
||
|
{
|
||
|
Console.WriteLine("TcpBlast to {0} at port {1} for {2} bytes in {3}-byte chunks",
|
||
|
address, port, numBytes, chunkSize);
|
||
|
|
||
|
Console.Write("Connecting...");
|
||
|
|
||
|
try
|
||
|
{
|
||
|
// Try to connect to the remote host
|
||
|
tcpConn.SendConnect((uint)address, port);
|
||
|
|
||
|
switch receive
|
||
|
{
|
||
|
case tcpConn.CouldNotConnect(TcpError error) :
|
||
|
Console.WriteLine("Failed to connect: TcpError = " + System.Net.Sockets.TcpException.GetMessageForTcpError(error));
|
||
|
delete tcpConn;
|
||
|
return -1;
|
||
|
break;
|
||
|
|
||
|
case tcpConn.OK() :
|
||
|
// success;
|
||
|
break;
|
||
|
|
||
|
case tcpConn.ChannelClosed() :
|
||
|
// how rude
|
||
|
Console.WriteLine("Netstack channel closed unexpectedly");
|
||
|
delete tcpConn;
|
||
|
return -1;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
Console.WriteLine("Connected");
|
||
|
byte[] in ExHeap buf;
|
||
|
uint bytesLeft = numBytes, patternLength = (uint)RepeatPattern.Length;
|
||
|
|
||
|
while (bytesLeft > 0) {
|
||
|
uint thisPass = chunkSize < bytesLeft ? chunkSize : bytesLeft;
|
||
|
buf = new[ExHeap] byte[thisPass];
|
||
|
|
||
|
for (uint i = 0; i < thisPass; i++) {
|
||
|
buf[(int)i] = (byte)RepeatPattern[(int)i % (int)patternLength];
|
||
|
}
|
||
|
|
||
|
tcpConn.SendWrite(buf);
|
||
|
|
||
|
switch receive
|
||
|
{
|
||
|
case tcpConn.OK() :
|
||
|
break;
|
||
|
|
||
|
case tcpConn.CantSend() :
|
||
|
Console.WriteLine("Connection closed unexpectedly");
|
||
|
delete tcpConn;
|
||
|
return -1;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
bytesLeft -= thisPass;
|
||
|
}
|
||
|
|
||
|
tcpConn.SendClose();
|
||
|
delete tcpConn;
|
||
|
Console.WriteLine("Done");
|
||
|
}
|
||
|
catch (Exception e) {
|
||
|
Console.WriteLine("Unexpected exception: {0}", e);
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
public static void Usage()
|
||
|
{
|
||
|
Console.WriteLine("tcpgulp <ipAddress> <port> <numBytes> <chunkSize>");
|
||
|
}
|
||
|
|
||
|
internal static int AppMain(Parameters! config)
|
||
|
{
|
||
|
IPv4 host;
|
||
|
try {
|
||
|
host = IPv4.Parse(config.address);
|
||
|
}
|
||
|
catch (FormatException e) {
|
||
|
Console.WriteLine("{0}: {1}", e, config.address);
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
|
||
|
if (config.port > 65536 || config.port < 0) {
|
||
|
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;
|
||
|
|
||
|
TcpContract.Imp tcpConn = (config.tcpRef).Acquire();
|
||
|
if (tcpConn == null)
|
||
|
{
|
||
|
Console.WriteLine("Could not initialize TCP endpoint.");
|
||
|
return 1;
|
||
|
}
|
||
|
tcpConn.RecvReady();
|
||
|
|
||
|
TcpConnectionContract.Imp! connImp;
|
||
|
TcpConnectionContract.Exp! connExp;
|
||
|
TcpConnectionContract.NewChannel(out connImp, out connExp);
|
||
|
|
||
|
tcpConn.SendCreateTcpSession(connExp);
|
||
|
connImp.RecvReady();
|
||
|
delete tcpConn;
|
||
|
|
||
|
return Blast(connImp, host, port, numBytes, chunkSize);
|
||
|
}
|
||
|
} // end class TcpBlast
|
||
|
}
|