Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Replace ICMP Ping by TCP Ping #10

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 54 additions & 11 deletions src/Nodsoft.YumeChan.Modules/Network/PingModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@
using Discord.Commands;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;

Expand All @@ -13,12 +15,6 @@ namespace Nodsoft.YumeChan.Modules.Network
[Group("ping")]
public class PingModule : ModuleBase<SocketCommandContext>
{
//[Command]
public async Task SimplePingCommand()
{
await ReplyAsync("Pong !");
}

[Command("")]
public async Task NetworkPingCommand(string host)
{
Expand All @@ -36,7 +32,7 @@ public async Task NetworkPingCommand(string host)

// 2. Ping the IP
int pingCount = 4;
PingReply[] pingReplies = ComplexPing(hostResolved, pingCount).Result;
PingModuleReply[] pingReplies = TcpPing(hostResolved, 80, pingCount).Result;

// 3. Retrieve statistics // 4. Return results to user with ReplyAsync(); (Perhaps Embed ?)
List<long> roundTripTimings = new List<long>();
Expand Down Expand Up @@ -67,10 +63,10 @@ public async Task NetworkPingCommand(string host)
await ReplyAsync(message: contextUser, embed: embedBuilder.Build()); //Quote user in main message, and attach Embed.
}

internal static async Task<PingReply[]> ComplexPing(IPAddress host, int count) => await ComplexPing(host, count, 2000, new PingOptions(64, true)).ConfigureAwait(false);
internal static async Task<PingReply[]> ComplexPing(IPAddress host, int count, int timeout, PingOptions options)
internal static async Task<PingModuleReply[]> ComplexPing(IPAddress host, int count) => await ComplexPing(host, count, 2000, new PingOptions(64, true)).ConfigureAwait(false);
internal static async Task<PingModuleReply[]> ComplexPing(IPAddress host, int count, int timeout, PingOptions options)
{
PingReply[] pingReplies = new PingReply[count];
PingModuleReply[] pingReplies = new PingModuleReply[count];

// Create a buffer of 32 bytes of data to be transmitted.
byte[] buffer = Encoding.ASCII.GetBytes("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
Expand All @@ -79,12 +75,59 @@ internal static async Task<PingReply[]> ComplexPing(IPAddress host, int count, i
for (int i = 0; i < count; i++)
{
Ping ping = new Ping();
pingReplies[i] = await ping.SendPingAsync(host, timeout, buffer, options).ConfigureAwait(false);
pingReplies[i] = new PingModuleReply(await ping.SendPingAsync(host, timeout, buffer, options).ConfigureAwait(false));
ping.Dispose();
}

return pingReplies;
}

// See : https://stackoverflow.com/questions/26067342/how-to-implement-psping-tcp-ping-in-c-sharp
internal static Task<PingModuleReply[]> TcpPing(IPAddress host, int port, int count)
{
PingModuleReply[] pingReplies = new PingModuleReply[count];
for (int i = 0; i < count; i++)
{
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socket.Blocking = true;

Stopwatch latencyMeasurement = new Stopwatch();
IPStatus? status = null;
try
{
latencyMeasurement.Start();
socket.Connect(host, port);
latencyMeasurement.Stop();
}
catch (Exception)
{
status = IPStatus.TimedOut;
}

pingReplies[i] = new PingModuleReply(host, latencyMeasurement.ElapsedMilliseconds, status ?? IPStatus.Success );
}

return Task.FromResult(pingReplies);
}

internal struct PingModuleReply
{
internal IPAddress Host { get; }
internal long RoundtripTime { get; }
internal IPStatus Status { get; }

public PingModuleReply(IPAddress host, long roundtripTime, IPStatus status)
{
Host = host;
RoundtripTime = roundtripTime;
Status = status;
}
public PingModuleReply(PingReply reply)
{
Host = reply.Address;
RoundtripTime = reply.RoundtripTime;
Status = reply.Status;
}
}
}
}
3 changes: 3 additions & 0 deletions src/Nodsoft.YumeChan.Modules/Status/Status.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ public async Task DefaultAsync()
.WithDescription("Status : Online")
.AddField("Core", $"Version : {(CoreVersion != null ? CoreVersion.ToString() : MissingVersionSubstitute)}", true)
.AddField("Modules", $"Version : {ModulesVersion}", true);
#if DEBUG
embed.AddField("Debug", "Debug Build Active.");
#endif

await ReplyAsync(embed: embed.Build());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<TargetFramework>netcoreapp3.0</TargetFramework>
<LangVersion>8.0</LangVersion>
<LangVersion>preview</LangVersion>
<Version>0.1.2</Version>
<Authors>DJ Daemonix</Authors>
<Company>Nodsoft ES</Company>
Expand Down