using System.Net.Sockets;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
public const string Pattern =
"(?:WAN2 total TX: )([0-9.]*) " +
"((?:[KMG]B)|(?:Bytes))" +
"(?:[, ]*RX: )([0-9.]*) " +
"((?:[KMG]B)|(?:Bytes))";
private const int TimeoutMs = 5000;
public async static Task Main()
using (var server = new DummyTelnetServer())
using (var client = new Client(
server.IPAddress.ToString(),
new CancellationToken()))
client.IsConnected.Should().Be(true);
Client.IsWriteConsole = true;
(await client.TryLoginAsync(
TimeoutMs)).Should().Be(true);
await client.WriteLineAsync("show statistic wan2");
string s = await client.TerminatedReadAsync(
TimeSpan.FromMilliseconds(TimeoutMs));
s.Should().Contain("WAN2");
var regEx = new Regex(Pattern);
regEx.IsMatch(s).Should().Be(true);
MatchCollection matches = regEx.Matches(s);
matches.Count.Should().Be(1);
matches[0].Captures.Count.Should().Be(1);
matches[0].Groups.Count.Should().Be(5);
matches[0].Groups[0].Value.Should().Be(
"WAN2 total TX: 6.3 GB ,RX: 6.9 GB");
matches[0].Groups[1].Value.Should().Be("6.3");
matches[0].Groups[2].Value.Should().Be("GB");
matches[0].Groups[3].Value.Should().Be("6.9");
matches[0].Groups[4].Value.Should().Be("GB");
var total = (ConvertToGigabytes(
matches[0].Groups[1].Value,
matches[0].Groups[2].Value) +
matches[0].Groups[3].Value,
matches[0].Groups[4].Value));
total.Should().Be(13.2M);
private static decimal ConvertToGigabytes(string value, string unit)
var result = decimal.Parse(value);
result *= 1024 * 1024 * 1024;
return Math.Round(result /= 1024 * 1024 * 1024, 3);
public class DummyTelnetServer : DummyTelnetServerBase
public DummyTelnetServer()
: base(Client.LegacyLineFeed)
public abstract class DummyTelnetServerBase : System.Net.Sockets.Socket
private readonly System.Threading.Thread t;
private readonly string expectedLineFeedTerminator;
protected DummyTelnetServerBase(string expectedLineFeedTerminator)
: base(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
this.expectedLineFeedTerminator = expectedLineFeedTerminator;
var ipHostInfo = Dns.GetHostEntry(Dns.GetHostName());
IPAddress = ipHostInfo.AddressList.First(o => o.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork);
t = new System.Threading.Thread(new System.Threading.ThreadStart(SpinListen));
protected override void Dispose(bool disposing)
System.Threading.Thread.Sleep(10);
public bool IsListening { get; private set; }
public void StopListening()
private readonly TimeSpan spinWait = TimeSpan.FromMilliseconds(10);
public IPAddress IPAddress { get; private set; }
public int Port { get; private set; }
private void SpinListen()
#pragma warning disable CA1031
var localEndPoint = new IPEndPoint(IPAddress, Port);
Console.WriteLine("Waiting for a connection...");
Console.WriteLine("Connection made, respond with Account: prompt");
handler.Send(Encoding.ASCII.GetBytes("Account:"));
WaitFor(handler, $"username{expectedLineFeedTerminator}");
Console.WriteLine("Account entered, respond with Password: prompt");
handler.Send(Encoding.ASCII.GetBytes("Password:"));
WaitFor(handler, $"password{expectedLineFeedTerminator}");
Console.WriteLine("Password entered, respond with Command> prompt");
handler.Send(Encoding.ASCII.GetBytes("Command >"));
WaitFor(handler, $"show statistic wan2{expectedLineFeedTerminator}");
Console.WriteLine("Command entered, respond with WAN2 terminated reply");
handler.Send(Encoding.ASCII.GetBytes("show statistic wan2\n\r WAN1 total TX: 0 Bytes ,RX: 0 Bytes \n\r WAN2 total TX: 6.3 GB ,RX: 6.9 GB \n\r WAN3 total TX: 0 Bytes ,RX: 0 Bytes \n\r WAN4 total TX: 0 Bytes ,RX: 0 Bytes \n\r WAN5 total TX: 0 Bytes ,RX: 0 Bytes \n\r>"));
System.Threading.Thread.Sleep(100);
handler.Shutdown(SocketShutdown.Both);
Console.WriteLine(e.ToString());
#pragma warning restore CA1031
private void WaitFor(Socket handler, string awaitedResponse)
data += ReceiveResponse(handler);
if (IsResponseReceived(data, awaitedResponse))
private static string ReceiveResponse(Socket handler)
var bytes = new byte[1024];
var bytesRec = handler.Receive(bytes);
return Encoding.ASCII.GetString(bytes, 0, bytesRec).Trim((char)255);
private bool IsResponseReceived(string currentResponse, string responseAwaited)
if (currentResponse.Contains(responseAwaited, StringComparison.InvariantCulture))
System.Diagnostics.Debug.Print("{0} response received", responseAwaited);
Console.WriteLine("{0} response received", responseAwaited);
System.Diagnostics.Debug.Print("Waiting for {1} response, received {0}", currentResponse, responseAwaited);
Console.WriteLine("Waiting for {1} response, received {0}", currentResponse, responseAwaited);
System.Threading.Thread.Sleep(spinWait);