Skip to content

Instantly share code, notes, and snippets.

@praeclarum
Created December 5, 2012 00:45
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save praeclarum/4210793 to your computer and use it in GitHub Desktop.
Save praeclarum/4210793 to your computer and use it in GitHub Desktop.
Code used to measure the network performance of an iPhone 5 while traveling around Seattle
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Threading;
using MonoTouch.Foundation;
using MonoTouch.UIKit;
using SQLite;
namespace LatencyMeasurement
{
public class Measurement
{
[PrimaryKey, AutoIncrement]
public int Id { get; set; }
public DateTime RequestTime { get; set; }
public DateTime ResponseTime { get; set; }
public double Duration { get; set; }
public string Error { get; set; }
public int ResponseContentLength { get; set; }
}
[Register ("AppDelegate")]
public class AppDelegate : UIApplicationDelegate
{
const string TestUrl = "https://news.google.com";
const int TimeoutMillis = 20 * 1000;
SQLiteConnection db;
UIWindow window;
UILabel label;
NSTimer timer;
public override bool FinishedLaunching (UIApplication app, NSDictionary options)
{
app.IdleTimerDisabled = true;
var dbPath = Path.Combine (
Environment.GetFolderPath (Environment.SpecialFolder.MyDocuments),
"Measurements.db");
Console.WriteLine (dbPath);
db = new SQLiteConnection (dbPath, true);
db.CreateTable<Measurement> ();
var vc = new UIViewController ();
label = new UILabel (new RectangleF (0, 100, 320, 60)) {
Font = UIFont.BoldSystemFontOfSize (50),
AdjustsFontSizeToFitWidth = true,
Text = "Hello",
TextAlignment = UITextAlignment.Center,
};
vc.View.AddSubview (label);
// Dump ();
timer = NSTimer.CreateRepeatingScheduledTimer (30, HandleTimer);
window = new UIWindow (UIScreen.MainScreen.Bounds);
window.RootViewController = vc;
window.MakeKeyAndVisible ();
return true;
}
void Dump ()
{
using (var w = new StreamWriter ("/Users/fak/Desktop/Results.csv")) {
var ms = db.Table<Measurement> ().OrderBy (x => x.RequestTime).Skip (2);
w.WriteLine ("Start Time,Duration,Content Length,Error");
foreach (var m in ms) {
w.WriteLine (
"{0},{1},{2},{3}",
m.RequestTime.ToLocalTime (),
m.Duration,
m.ResponseContentLength,
m.Error);
}
}
}
void Display (string format, params object[] args)
{
BeginInvokeOnMainThread (() => {
label.Text = string.Format (format, args);
});
}
void HandleTimer ()
{
ThreadPool.QueueUserWorkItem (o => {
var buffer = new byte[16*1024];
var length = 0;
Display ("Requesting...");
var req = (HttpWebRequest)WebRequest.Create (TestUrl);
var m = new Measurement ();
m.RequestTime = DateTime.UtcNow;
try {
req.Timeout = TimeoutMillis;
req.ReadWriteTimeout = TimeoutMillis;
req.KeepAlive = false;
var res = req.GetResponse ();
Display ("Receiving...");
var n = 0;
using (var s = res.GetResponseStream ()) {
for (;;) {
n = s.Read (buffer, 0, buffer.Length);
if (n <= 0) {
break;
}
else {
length += n;
}
}
}
m.Error = "";
} catch (Exception ex) {
m.Error = ex.GetType () + ": " + ex.Message;
}
m.ResponseContentLength = length;
m.ResponseTime = DateTime.UtcNow;
m.Duration = (m.ResponseTime - m.RequestTime).TotalSeconds;
if (m.Duration <= 1e-3) {
m.Duration = 1e-3;
}
db.Insert (m);
Display ("{0:#,##0} B/s", m.ResponseContentLength / m.Duration);
});
}
static void Main (string[] args)
{
UIApplication.Main (args, null, "AppDelegate");
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment