//////////////////////////////////////////////////////////////////////////////// // // Microsoft Research Singularity // // Copyright (c) Microsoft Corporation. All rights reserved. // // File: TcpGulp.cs // // 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="Blast TCP data to a ipAddress, port", DefaultAction=true)] internal class Parameters { [InputEndpoint("data")] public readonly TRef Stdin; [OutputEndpoint("data")] public readonly TRef Stdout; [Endpoint] public readonly TRef 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 "); } 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 }