194 lines
6.4 KiB
C#
194 lines
6.4 KiB
C#
////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Microsoft Research Singularity
|
|
//
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
//
|
|
// Note: Simple Singularity test program.
|
|
//
|
|
using System;
|
|
using System.Diagnostics;
|
|
using System.Net.IP;
|
|
|
|
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="Gulp TCP data from an 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( "ipAddress", Mandatory=true, Position=0, HelpMessage="IP Address to send to")]
|
|
internal string ipAddress;
|
|
|
|
|
|
[StringParameter( "port", Mandatory=true, Position=1, HelpMessage="port to blats")]
|
|
internal string port;
|
|
|
|
reflective internal Parameters();
|
|
|
|
internal int AppMain() {
|
|
return TcpGulp.AppMain(this);
|
|
}
|
|
}
|
|
|
|
public class TcpGulp
|
|
{
|
|
public static int Gulp(TcpConnectionContract.Imp:ReadyState! tcpConn, IPv4 address, ushort port)
|
|
{
|
|
Console.WriteLine("TcpGulp({0}, {1})", address, port);
|
|
|
|
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));
|
|
return -1;
|
|
}
|
|
break;
|
|
|
|
case tcpConn.OK() :
|
|
// success;
|
|
break;
|
|
|
|
case tcpConn.ChannelClosed() :
|
|
// how rude
|
|
Console.WriteLine("Netstack channel closed unexpectedly");
|
|
return -1;
|
|
break;
|
|
}
|
|
|
|
Console.WriteLine("Connected");
|
|
bool connected = true;
|
|
int messages = 0;
|
|
int bytesRead = 0;
|
|
|
|
while (connected) {
|
|
tcpConn.SendRead();
|
|
|
|
switch receive {
|
|
case tcpConn.Data(byte[]! in ExHeap data) :
|
|
Console.Write('.');
|
|
messages++;
|
|
bytesRead += data.Length;
|
|
#if false
|
|
Console.WriteLine("Read {0} bytes :", data.Length);
|
|
|
|
for (int i = 0; i < data.Length; ++i) {
|
|
if (data[i] < 32) {
|
|
Console.Write("<" + (int)data[i] + ">");
|
|
}
|
|
else {
|
|
Console.Write((char)data[i]);
|
|
}
|
|
}
|
|
#endif
|
|
delete data;
|
|
break;
|
|
|
|
case tcpConn.ConnectionClosed() :
|
|
tcpConn.SendClose(); // Zombie -> Closed
|
|
connected = false;
|
|
break;
|
|
|
|
case tcpConn.NoMoreData() :
|
|
// We're never going to send anything
|
|
tcpConn.SendClose(); // SendOnly -> Closed
|
|
connected = false;
|
|
break;
|
|
|
|
case tcpConn.ChannelClosed() :
|
|
// How rude
|
|
connected = false;
|
|
break;
|
|
}
|
|
}
|
|
|
|
Console.WriteLine("\nConnection closed");
|
|
Console.WriteLine("got {0} messages {1} bytes ",
|
|
messages, bytesRead);
|
|
}
|
|
catch (Exception e) {
|
|
Console.WriteLine("Unexpected exception: {0}", e);
|
|
}
|
|
finally {
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
public static void Usage()
|
|
{
|
|
Console.WriteLine("tcpgulp <ipAddress> <port>");
|
|
}
|
|
|
|
internal static int AppMain(Parameters! config)
|
|
{
|
|
IPv4 host;
|
|
|
|
|
|
|
|
try {
|
|
host = IPv4.Parse(config.ipAddress);
|
|
}
|
|
catch (FormatException e) {
|
|
Console.WriteLine("{0}: {1}", e, config.ipAddress);
|
|
return -1;
|
|
}
|
|
|
|
ushort port;
|
|
try {
|
|
port = UInt16.Parse(config.port);
|
|
}
|
|
catch (FormatException) {
|
|
Console.WriteLine("Malformed port number: {0}", config.port);
|
|
return -1;
|
|
}
|
|
catch (OverflowException) {
|
|
Console.WriteLine("Port number out of range: {0}", config.port);
|
|
return -1;
|
|
}
|
|
|
|
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;
|
|
|
|
int result = Gulp(connImp, host, port);
|
|
delete connImp;
|
|
return result;
|
|
}
|
|
} // end class TcpGulp
|
|
}
|