/base/Applications/Network/UdpGulp/UdpGulp.cs
C# | 195 lines | 152 code | 30 blank | 13 comment | 8 complexity | ed40762c7d2ff04e904850a26125cef2 MD5 | raw file
- ////////////////////////////////////////////////////////////////////////////////
- //
- // 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 System.Threading;
-
- using Microsoft.Singularity;
- using Microsoft.SingSharp;
- 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="Receive UDP data from 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<UdpContract.Imp:Start> udpRef;
-
- [LongParameter("t", Mandatory = false, HelpMessage = "Seconds to send packets for", Default = 30)]
- internal long seconds;
-
- [StringParameter("a", Mandatory = false, HelpMessage = "Local address to bind to.", Default = "0.0.0.0")]
- internal string address;
-
- [LongParameter("port", Mandatory = true, Position = 0, HelpMessage = "port to gulp from")]
- internal long port;
-
- reflective internal Parameters();
-
- internal int AppMain()
- {
- return UdpGulp.AppMain(this);
- }
- }
-
- public class UdpGulp
- {
- private const int FixedHeaderBytes = 42; // Ether + IP + UDP
-
- private static void
- ReceivePackets(
- UdpConnectionContract.Imp:ReadyState! udpConn,
- long totalSeconds
- )
- {
- int bytesThisRound = 0;
- int packetsThisRound = 0;
-
- DateTime now = DateTime.Now;
- DateTime epochEnd = now + TimeSpan.FromSeconds(1);
- DateTime epochStart = now;
-
- while (--totalSeconds >= 0) {
- while (now < epochEnd) {
- udpConn.SendPollRead((epochEnd - now).Milliseconds);
- switch receive {
- case udpConn.NoData() :
- // No data to read. This doesn't
- // necessarily mean the connection
- // is closed.
- Thread.Yield();
- break;
- case udpConn.Data(uint addr, ushort port2, byte[]! in ExHeap data):
- bytesThisRound += data.Length + FixedHeaderBytes;
- packetsThisRound++;
- delete data;
- break;
- case udpConn.ChannelClosed():
- throw new Exception("udpConn channel closed");
- }
- now = DateTime.Now;
- }
-
- TimeSpan delta = now - epochStart;
- string msg = String.Format(
- "Duration(s) {0:f2} rate {1:e3} bps, {2:e3} bytes/sec, {3:e3} pps",
- delta.TotalSeconds,
- 8.0 * bytesThisRound / delta.TotalSeconds,
- 8.0 * bytesThisRound / delta.TotalSeconds,
- 1.0 * packetsThisRound / delta.TotalSeconds
- );
-
- Console.WriteLine(msg);
- DebugStub.WriteLine(msg);
-
- bytesThisRound = 0;
- packetsThisRound = 0;
- epochStart = DateTime.Now;
- epochEnd = epochStart + TimeSpan.FromSeconds(1);
- }
- }
-
- public static int
- Gulp([Claims] UdpConnectionContract.Imp:ReadyState! udpConn,
- IPv4 address,
- ushort port,
- long totalSeconds)
- {
- Console.WriteLine("UdpGulp({0}, {1})", address, port);
-
- try {
- // Bind local endpoint
- udpConn.SendBindLocalEndPoint((uint)address, port);
-
- switch receive {
- case udpConn.OK() :
- // success;
- Console.WriteLine("Connected");
- break;
-
- case udpConn.InvalidEndPoint(ip, rejectedPort) :
- throw new Exception("udpConn address and port rejected");
-
- case udpConn.ChannelClosed() :
- throw new Exception("udpConn channel closed");
- }
-
- ReceivePackets(udpConn, totalSeconds);
-
- Console.WriteLine("Closing connection");
- udpConn.SendClose();
- }
- catch (Exception e) {
- Console.WriteLine("Unexpected exception: {0}", e);
- }
- finally {
- delete udpConn;
- }
- return 0;
- }
-
- 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 > 0xffff || config.port < 0) {
- Console.WriteLine("Port number out of range: {0}",
- config.port);
- return -1;
- }
- ushort port = (ushort) config.port;
-
- UdpContract.Imp udpConn = ((!)config.udpRef).Acquire();
- if (udpConn == null) {
- Console.WriteLine("Could not initialize TCP endpoint.");
- return 1;
- }
-
- Console.WriteLine("Waiting for ready");
- udpConn.RecvReady();
-
- UdpConnectionContract.Imp! connImp;
- UdpConnectionContract.Exp! connExp;
- UdpConnectionContract.NewChannel(out connImp, out connExp);
-
- Console.WriteLine("Creating session");
- udpConn.SendCreateUdpSession(connExp);
- connImp.RecvReady();
- delete udpConn;
- Console.WriteLine("Ready");
- return Gulp(connImp, host, port, config.seconds);
- }
- } // end class UdpGulp
- }