Skip to content

Commit

Permalink
Add support UDS(Unix Domain Socket) - Server/Client #135
Browse files Browse the repository at this point in the history
  • Loading branch information
chronoxor committed Jan 9, 2022
1 parent 2bf5d96 commit c259786
Show file tree
Hide file tree
Showing 13 changed files with 761 additions and 5 deletions.
44 changes: 44 additions & 0 deletions NetCoreServer.sln
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,14 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UdsChatClient", "examples\U
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UdsChatServer", "examples\UdsChatServer\UdsChatServer.csproj", "{F69349F3-47EE-4C82-B714-83E9B6E931CC}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UdsEchoClient", "performance\UdsEchoClient\UdsEchoClient.csproj", "{CA20DA7E-5E5E-4495-9F02-6D5D18558C77}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UdsEchoServer", "performance\UdsEchoServer\UdsEchoServer.csproj", "{13567A7F-923D-42C0-9451-A1821E087A69}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UdsMulticastClient", "performance\UdsMulticastClient\UdsMulticastClient.csproj", "{B1D5EA8F-9A1E-4AD6-9C40-A6A5EFDDE044}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UdsMulticastServer", "performance\UdsMulticastServer\UdsMulticastServer.csproj", "{80C95510-AF12-4CF0-8852-B21241F6C1F3}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -455,6 +463,38 @@ Global
{F69349F3-47EE-4C82-B714-83E9B6E931CC}.Release|Any CPU.Build.0 = Release|Any CPU
{F69349F3-47EE-4C82-B714-83E9B6E931CC}.Release|x64.ActiveCfg = Release|Any CPU
{F69349F3-47EE-4C82-B714-83E9B6E931CC}.Release|x64.Build.0 = Release|Any CPU
{CA20DA7E-5E5E-4495-9F02-6D5D18558C77}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CA20DA7E-5E5E-4495-9F02-6D5D18558C77}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CA20DA7E-5E5E-4495-9F02-6D5D18558C77}.Debug|x64.ActiveCfg = Debug|Any CPU
{CA20DA7E-5E5E-4495-9F02-6D5D18558C77}.Debug|x64.Build.0 = Debug|Any CPU
{CA20DA7E-5E5E-4495-9F02-6D5D18558C77}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CA20DA7E-5E5E-4495-9F02-6D5D18558C77}.Release|Any CPU.Build.0 = Release|Any CPU
{CA20DA7E-5E5E-4495-9F02-6D5D18558C77}.Release|x64.ActiveCfg = Release|Any CPU
{CA20DA7E-5E5E-4495-9F02-6D5D18558C77}.Release|x64.Build.0 = Release|Any CPU
{13567A7F-923D-42C0-9451-A1821E087A69}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{13567A7F-923D-42C0-9451-A1821E087A69}.Debug|Any CPU.Build.0 = Debug|Any CPU
{13567A7F-923D-42C0-9451-A1821E087A69}.Debug|x64.ActiveCfg = Debug|Any CPU
{13567A7F-923D-42C0-9451-A1821E087A69}.Debug|x64.Build.0 = Debug|Any CPU
{13567A7F-923D-42C0-9451-A1821E087A69}.Release|Any CPU.ActiveCfg = Release|Any CPU
{13567A7F-923D-42C0-9451-A1821E087A69}.Release|Any CPU.Build.0 = Release|Any CPU
{13567A7F-923D-42C0-9451-A1821E087A69}.Release|x64.ActiveCfg = Release|Any CPU
{13567A7F-923D-42C0-9451-A1821E087A69}.Release|x64.Build.0 = Release|Any CPU
{B1D5EA8F-9A1E-4AD6-9C40-A6A5EFDDE044}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B1D5EA8F-9A1E-4AD6-9C40-A6A5EFDDE044}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B1D5EA8F-9A1E-4AD6-9C40-A6A5EFDDE044}.Debug|x64.ActiveCfg = Debug|Any CPU
{B1D5EA8F-9A1E-4AD6-9C40-A6A5EFDDE044}.Debug|x64.Build.0 = Debug|Any CPU
{B1D5EA8F-9A1E-4AD6-9C40-A6A5EFDDE044}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B1D5EA8F-9A1E-4AD6-9C40-A6A5EFDDE044}.Release|Any CPU.Build.0 = Release|Any CPU
{B1D5EA8F-9A1E-4AD6-9C40-A6A5EFDDE044}.Release|x64.ActiveCfg = Release|Any CPU
{B1D5EA8F-9A1E-4AD6-9C40-A6A5EFDDE044}.Release|x64.Build.0 = Release|Any CPU
{80C95510-AF12-4CF0-8852-B21241F6C1F3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{80C95510-AF12-4CF0-8852-B21241F6C1F3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{80C95510-AF12-4CF0-8852-B21241F6C1F3}.Debug|x64.ActiveCfg = Debug|Any CPU
{80C95510-AF12-4CF0-8852-B21241F6C1F3}.Debug|x64.Build.0 = Debug|Any CPU
{80C95510-AF12-4CF0-8852-B21241F6C1F3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{80C95510-AF12-4CF0-8852-B21241F6C1F3}.Release|Any CPU.Build.0 = Release|Any CPU
{80C95510-AF12-4CF0-8852-B21241F6C1F3}.Release|x64.ActiveCfg = Release|Any CPU
{80C95510-AF12-4CF0-8852-B21241F6C1F3}.Release|x64.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -502,6 +542,10 @@ Global
{20E95322-2F84-4147-8014-E50312D86CE5} = {8965E5CD-E36E-4DC5-A36E-827AFFC642D1}
{7ED276AD-8EF0-44A5-87B6-60AAA822C5FF} = {81ED94B5-0C65-432C-AEF5-67C3DFF7F2EE}
{F69349F3-47EE-4C82-B714-83E9B6E931CC} = {81ED94B5-0C65-432C-AEF5-67C3DFF7F2EE}
{CA20DA7E-5E5E-4495-9F02-6D5D18558C77} = {8965E5CD-E36E-4DC5-A36E-827AFFC642D1}
{13567A7F-923D-42C0-9451-A1821E087A69} = {8965E5CD-E36E-4DC5-A36E-827AFFC642D1}
{B1D5EA8F-9A1E-4AD6-9C40-A6A5EFDDE044} = {8965E5CD-E36E-4DC5-A36E-827AFFC642D1}
{80C95510-AF12-4CF0-8852-B21241F6C1F3} = {8965E5CD-E36E-4DC5-A36E-827AFFC642D1}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {64415837-63D9-474E-A25C-EE91C9CA90C5}
Expand Down
84 changes: 84 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,14 @@ Has integration with message protocol based on [Fast Binary Encoding](https://gi
* [TCP echo server](#tcp-echo-server)
* [SSL echo server](#ssl-echo-server)
* [UDP echo server](#udp-echo-server)
* [Unix Domain Socket echo server](#unix-domain-socket-echo-server)
* [WebSocket echo server](#websocket-echo-server)
* [WebSocket secure echo server](#websocket-secure-echo-server)
* [Benchmark: Multicast](#benchmark-multicast)
* [TCP multicast server](#tcp-multicast-server)
* [SSL multicast server](#ssl-multicast-server)
* [UDP multicast server](#udp-multicast-server)
* [Unix Domain Socket multicast server](#unix-domain-socket-multicast-server)
* [WebSocket multicast server](#websocket-multicast-server)
* [WebSocket secure multicast server](#websocket-secure-multicast-server)
* [Benchmark: Web Server](#benchmark-web-server)
Expand Down Expand Up @@ -2643,6 +2645,48 @@ Message latency: 15.950 mcs
Message throughput: 62693 msg/s
```

### Unix Domain Socket echo server

* [UdsEchoServer](https://github.com/chronoxor/NetCoreServer/blob/master/performance/UdsEchoServer/Program.cs)
* [UdsEchoClient](https://github.com/chronoxor/NetCoreServer/blob/master/performance/UdsEchoClient/Program.cs) --clients 1

```
Server Unix Domain Socket path: C:\Users\chronoxor\AppData\Local\Temp\echo.sock
Working clients: 1
Working messages: 1000
Message size: 32
Seconds to benchmarking: 10
Errors: 0
Total time: 10.016 s
Total data: 208.657 MiB
Total messages: 6836769
Data throughput: 20.850 MiB/s
Message latency: 1.465 mcs
Message throughput: 682575 msg/s
```

* [UdsEchoServer](https://github.com/chronoxor/NetCoreServer/blob/master/performance/UdsEchoServer/Program.cs)
* [UdsEchoClient](https://github.com/chronoxor/NetCoreServer/blob/master/performance/UdsEchoClient/Program.cs) --clients 100

```
Server Unix Domain Socket path: C:\Users\chronoxor\AppData\Local\Temp\echo.sock
Working clients: 100
Working messages: 1000
Message size: 32
Seconds to benchmarking: 10
Errors: 0
Total time: 12.253 s
Total data: 602.320 MiB
Total messages: 19736578
Data throughput: 49.157 MiB/s
Message latency: 620 ns
Message throughput: 1610666 msg/s
```

### WebSocket echo server

* [WsEchoServer](https://github.com/chronoxor/NetCoreServer/blob/master/performance/WsEchoServer/Program.cs)
Expand Down Expand Up @@ -2866,6 +2910,46 @@ Message latency: 10.682 mcs
Message throughput: 93606 msg/s
```

### Unix Domain Socket multicast server

* [UdsMulticastServer](https://github.com/chronoxor/NetCoreServer/blob/master/performance/UdsMulticastServer/Program.cs)
* [UdsMulticastClient](https://github.com/chronoxor/NetCoreServer/blob/master/performance/UdsMulticastClient/Program.cs) --clients 1

```
Server Unix Domain Socket path: C:\Users\chronoxor\AppData\Local\Temp\multicast.sock
Working clients: 1
Message size: 32
Seconds to benchmarking: 10
Errors: 0
Total time: 10.015 s
Total data: 204.127 MiB
Total messages: 6688763
Data throughput: 20.390 MiB/s
Message latency: 1.497 mcs
Message throughput: 667869 msg/s
```

* [UdsMulticastServer](https://github.com/chronoxor/NetCoreServer/blob/master/performance/UdsMulticastServer/Program.cs)
* [UdsMulticastClient](https://github.com/chronoxor/NetCoreServer/blob/master/performance/UdsMulticastClient/Program.cs) --clients 100

```
Server Unix Domain Socket path: C:\Users\chronoxor\AppData\Local\Temp\multicast.sock
Working clients: 100
Message size: 32
Seconds to benchmarking: 10
Errors: 0
Total time: 10.033 s
Total data: 124.463 MiB
Total messages: 4078051
Data throughput: 12.413 MiB/s
Message latency: 2.460 mcs
Message throughput: 406451 msg/s
```

### WebSocket multicast server

* [WsMulticastServer](https://github.com/chronoxor/NetCoreServer/blob/master/performance/WsMulticastServer/Program.cs)
Expand Down
2 changes: 1 addition & 1 deletion examples/UdsChatClient/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ class Program
static void Main(string[] args)
{
// Unix Domain Socket path
string path = Path.GetTempPath() + Path.DirectorySeparatorChar + "chat.sock";
string path = Path.Combine(Path.GetTempPath(), "chat.sock");
if (args.Length > 0)
path = args[0];

Expand Down
2 changes: 1 addition & 1 deletion examples/UdsChatServer/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ class Program
static void Main(string[] args)
{
// Unix Domain Socket path
string path = Path.GetTempPath() + Path.DirectorySeparatorChar + "chat.sock";
string path = Path.Combine(Path.GetTempPath(), "chat.sock");
if (args.Length > 0)
path = args[0];

Expand Down
170 changes: 170 additions & 0 deletions performance/UdsEchoClient/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Net.Sockets;
using System.Threading;
using NetCoreServer;
using NDesk.Options;

namespace UdsEchoClient
{
class EchoClient : UdsClient
{
public EchoClient(string path, int messages) : base(path)
{
_messages = messages;
}

protected override void OnConnected()
{
for (long i = _messages; i > 0; i--)
SendMessage();
}

protected override void OnSent(long sent, long pending)
{
_sent += sent;
}

protected override void OnReceived(byte[] buffer, long offset, long size)
{
_received += size;
while (_received >= Program.MessageToSend.Length)
{
SendMessage();
_received -= Program.MessageToSend.Length;
}

Program.TimestampStop = DateTime.UtcNow;
Program.TotalBytes += size;
}

protected override void OnError(SocketError error)
{
Console.WriteLine($"Client caught an error with code {error}");
Program.TotalErrors++;
}

private void SendMessage()
{
SendAsync(Program.MessageToSend);
}

private long _sent;
private long _received;
private long _messages;
}

class Program
{
public static byte[] MessageToSend;
public static DateTime TimestampStart = DateTime.UtcNow;
public static DateTime TimestampStop = DateTime.UtcNow;
public static long TotalErrors;
public static long TotalBytes;
public static long TotalMessages;

static void Main(string[] args)
{
bool help = false;
string path = Path.Combine(Path.GetTempPath(), "echo.sock");
int clients = 100;
int messages = 1000;
int size = 32;
int seconds = 10;

var options = new OptionSet()
{
{ "h|?|help", v => help = v != null },
{ "p|path=", v => path = v },
{ "c|clients=", v => clients = int.Parse(v) },
{ "m|messages=", v => messages = int.Parse(v) },
{ "s|size=", v => size = int.Parse(v) },
{ "z|seconds=", v => seconds = int.Parse(v) }
};

try
{
options.Parse(args);
}
catch (OptionException e)
{
Console.Write("Command line error: ");
Console.WriteLine(e.Message);
Console.WriteLine("Try `--help' to get usage information.");
return;
}

if (help)
{
Console.WriteLine("Usage:");
options.WriteOptionDescriptions(Console.Out);
return;
}

Console.WriteLine($"Server Unix Domain Socket path: {path}");
Console.WriteLine($"Working clients: {clients}");
Console.WriteLine($"Working messages: {messages}");
Console.WriteLine($"Message size: {size}");
Console.WriteLine($"Seconds to benchmarking: {seconds}");

Console.WriteLine();

// Prepare a message to send
MessageToSend = new byte[size];

// Create echo clients
var echoClients = new List<EchoClient>();
for (int i = 0; i < clients; i++)
{
var client = new EchoClient(path, messages);
echoClients.Add(client);
}

TimestampStart = DateTime.UtcNow;

// Connect clients
Console.Write("Clients connecting...");
foreach (var client in echoClients)
client.ConnectAsync();
Console.WriteLine("Done!");
foreach (var client in echoClients)
while (!client.IsConnected)
Thread.Yield();
Console.WriteLine("All clients connected!");

// Wait for benchmarking
Console.Write("Benchmarking...");
Thread.Sleep(seconds * 1000);
Console.WriteLine("Done!");

// Disconnect clients
Console.Write("Clients disconnecting...");
foreach (var client in echoClients)
client.Disconnect();
Console.WriteLine("Done!");
foreach (var client in echoClients)
while (client.IsConnected)
Thread.Yield();
Console.WriteLine("All clients disconnected!");

Console.WriteLine();

Console.WriteLine($"Errors: {TotalErrors}");

Console.WriteLine();

TotalMessages = TotalBytes / size;

Console.WriteLine($"Total time: {Utilities.GenerateTimePeriod((TimestampStop - TimestampStart).TotalMilliseconds)}");
Console.WriteLine($"Total data: {Utilities.GenerateDataSize(TotalBytes)}");
Console.WriteLine($"Total messages: {TotalMessages}");
Console.WriteLine($"Data throughput: {Utilities.GenerateDataSize((long)(TotalBytes / (TimestampStop - TimestampStart).TotalSeconds))}/s");
if (TotalMessages > 0)
{
Console.WriteLine($"Message latency: {Utilities.GenerateTimePeriod((TimestampStop - TimestampStart).TotalMilliseconds / TotalMessages)}");
Console.WriteLine($"Message throughput: {(long)(TotalMessages / (TimestampStop - TimestampStart).TotalSeconds)} msg/s");
}
}
}
}
16 changes: 16 additions & 0 deletions performance/UdsEchoClient/UdsEchoClient.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="NDesk.Options.Core" Version="1.2.5" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\source\NetCoreServer\NetCoreServer.csproj" />
</ItemGroup>

</Project>
Loading

0 comments on commit c259786

Please sign in to comment.