singrdk/base/Applications/Network/UdpGulp/UdpGulp.cs

196 lines
6.7 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.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
)
{
2008-11-17 18:29:00 -05:00
int bytesThisRound = 0;
int packetsThisRound = 0;
2008-03-05 09:52:00 -05:00
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();
2008-11-17 18:29:00 -05:00
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");
2008-03-05 09:52:00 -05:00
}
now = DateTime.Now;
}
TimeSpan delta = now - epochStart;
2008-11-17 18:29:00 -05:00
string msg = String.Format(
"Duration(s) {0:f2} rate {1:e3} bps, {2:e3} bytes/sec, {3:e3} pps",
2008-03-05 09:52:00 -05:00
delta.TotalSeconds,
2008-11-17 18:29:00 -05:00
8.0 * bytesThisRound / delta.TotalSeconds,
8.0 * bytesThisRound / delta.TotalSeconds,
1.0 * packetsThisRound / delta.TotalSeconds
);
Console.WriteLine(msg);
DebugStub.WriteLine(msg);
2008-03-05 09:52:00 -05:00
bytesThisRound = 0;
2008-11-17 18:29:00 -05:00
packetsThisRound = 0;
2008-03-05 09:52:00 -05:00
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();
}
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);
}
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;
2008-11-17 18:29:00 -05:00
UdpContract.Imp udpConn = ((!)config.udpRef).Acquire();
2008-03-05 09:52:00 -05:00
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
}