Repository files navigation

NETCoreServer

Windows build status

Ultra fast and low latency asynchronous socket server & client C# .NET Core library with support TCP, SSL, UDP protocols and 10K connections problem solution.

NETCoreServer documentation
NETCoreServer downloads

Contents

Features

Requirements

How to build?

Setup repository

git clone https://github.com/chronoxor/NETCoreServer.git
cd NETCoreServer

Windows (Visual Studio)

Open and build NETCoreServer.sln or run the build script:

cd build
vs.bat

The build script will create "release" directory with zip files:

  • NETCoreServer.zip - C# Server assembly
  • Benchmarks.zip - C# Server benchmarks
  • Examples.zip - C# Server examples

Examples

Example: Asio timer

Here comes the example of Asio timer. It can be used to wait for some action in future with providing absolute time or relative time span. Asio timer can be used in synchronous or asynchronous modes.

usingSystem;usingSystem.Threading;usingNETCoreServer;namespaceAsioTimer{classAsioTimer:Timer{publicAsioTimer(Serviceservice):base(service){}protectedoverridevoidOnTimer(boolcanceled){Console.WriteLine("Asio timer "+(canceled?"canceled":"expired"));}protectedoverridevoidOnError(interror,stringcategory,stringmessage){Console.WriteLine($"Asio timer caught an error with code {error} and category '{category}': {message}");}}classProgram{staticvoidMain(){// Create a new servicevarservice=newService();// Start the serviceConsole.Write("Service starting...");service.Start();Console.WriteLine("Done!");// Create a new Asio timervartimer=newAsioTimer(service);// Setup and synchronously wait for the timertimer.Setup(DateTime.UtcNow.AddSeconds(1));timer.WaitSync();// Setup and asynchronously wait for the timertimer.Setup(TimeSpan.FromSeconds(1));timer.WaitAsync();// Wait for a while...Thread.Sleep(2000);// Setup and asynchronously wait for the timertimer.Setup(TimeSpan.FromSeconds(1));timer.WaitAsync();// Wait for a while...Thread.Sleep(500);// Cancel the timertimer.Cancel();// Wait for a while...Thread.Sleep(500);// Stop the serviceConsole.Write("Service stopping...");service.Stop();Console.WriteLine("Done!");}}}

Output of the above example is the following:

Service starting...Done!
Asio timer expired
Asio timer canceled
Service stopping...Done!

Example: TCP chat server

Here comes the example of the TCP chat server. It handles multiple TCP client sessions and multicast received message from any session to all ones. Also it is possible to send admin message directly from the server.

usingSystem;usingSystem.Text;usingNETCoreServer;namespaceTcpChatServer{classChatSession:TcpSession{publicChatSession(TcpServerserver):base(server){}protectedoverridevoidOnConnected(){Console.WriteLine($"Chat TCP session with Id {Id} connected!");// Send invite messagestringmessage="Hello from TCP chat! Please send a message or '!' to disconnect the client!";Send(message);}protectedoverridevoidOnDisconnected(){Console.WriteLine($"Chat TCP session with Id {Id} disconnected!");}protectedoverridevoidOnReceived(byte[]buffer){stringmessage=Encoding.UTF8.GetString(buffer);Console.WriteLine("Incoming: "+message);// Multicast message to all connected sessionsServer.Multicast(message);// If the buffer starts with '!' the disconnect the current sessionif(message=="!")Disconnect();}protectedoverridevoidOnError(interror,stringcategory,stringmessage){Console.WriteLine($"Chat TCP session caught an error with code {error} and category '{category}': {message}");}}classChatServer:TcpServer{publicChatServer(Serviceservice,InternetProtocolprotocol,intport):base(service,protocol,port){}protectedoverrideTcpSessionCreateSession(){returnnewChatSession(this);}protectedoverridevoidOnError(interror,stringcategory,stringmessage){Console.WriteLine($"Chat TCP server caught an error with code {error} and category '{category}': {message}");}}classProgram{staticvoidMain(string[]args){// TCP server portintport=1111;if(args.Length>0)port=int.Parse(args[0]);Console.WriteLine($"TCP server port: {port}");// Create a new servicevarservice=newService();// Start the serviceConsole.Write("Service starting...");service.Start();Console.WriteLine("Done!");// Create a new TCP chat servervarserver=newChatServer(service,InternetProtocol.IPv4,port);// Start the serverConsole.Write("Server starting...");server.Start();Console.WriteLine("Done!");Console.WriteLine("Press Enter to stop the server or '!' to restart the server...");// Perform text inputfor(;;){stringline=Console.ReadLine();if(line==String.Empty)break;// Restart the serverif(line=="!"){Console.Write("Server restarting...");server.Restart();Console.WriteLine("Done!");continue;}// Multicast admin message to all sessionsline="(admin) "+line;server.Multicast(line);}// Stop the serverConsole.Write("Server stopping...");server.Stop();Console.WriteLine("Done!");// Stop the serviceConsole.Write("Service stopping...");service.Stop();Console.WriteLine("Done!");}}}

Example: TCP chat client

Here comes the example of the TCP chat client. It connects to the TCP chat server and allows to send message to it and receive new messages.

usingSystem;usingSystem.Text;usingSystem.Threading;usingNETCoreServer;namespaceTcpChatClient{classChatClient:TcpClient{publicChatClient(Serviceservice,stringaddress,intport):base(service,address,port){}publicvoidDisconnectAndStop(){_stop=true;Disconnect();while(IsConnected)Thread.Yield();}protectedoverridevoidOnConnected(){Console.WriteLine($"Chat TCP client connected a new session with Id {Id}");}protectedoverridevoidOnDisconnected(){Console.WriteLine($"Chat TCP client disconnected a session with Id {Id}");// Wait for a while...Thread.Sleep(1000);// Try to connect againif(!_stop)Connect();}protectedoverridevoidOnReceived(byte[]buffer){Console.WriteLine(Encoding.UTF8.GetString(buffer));}protectedoverridevoidOnError(interror,stringcategory,stringmessage){Console.WriteLine($"Chat TCP client caught an error with code {error} and category '{category}': {message}");}privatebool_stop;}classProgram{staticvoidMain(string[]args){// TCP server addressstringaddress="127.0.0.1";if(args.Length>0)address=args[0];// TCP server portintport=1111;if(args.Length>1)port=int.Parse(args[1]);Console.WriteLine($"TCP server address: {address}");Console.WriteLine($"TCP server port: {port}");// Create a new servicevarservice=newService();// Start the serviceConsole.Write("Service starting...");service.Start();Console.WriteLine("Done!");// Create a new TCP chat clientvarclient=newChatClient(service,address,port);// Connect the clientConsole.Write("Client connecting...");client.Connect();Console.WriteLine("Done!");Console.WriteLine("Press Enter to stop the client or '!' to reconnect the client...");// Perform text inputfor(;;){stringline=Console.ReadLine();if(line==String.Empty)break;// Disconnect the clientif(line=="!"){Console.Write("Client disconnecting...");client.Disconnect();Console.WriteLine("Done!");continue;}// Send the entered text to the chat serverclient.Send(line);}// Disconnect the clientConsole.Write("Client disconnecting...");client.DisconnectAndStop();Console.WriteLine("Done!");// Stop the serviceConsole.Write("Service stopping...");service.Stop();Console.WriteLine("Done!");}}}

Example: SSL chat server

Here comes the example of the SSL chat server. It handles multiple SSL client sessions and multicast received message from any session to all ones. Also it is possible to send admin message directly from the server.

This example is very similar to the TCP one except the code that prepares SSL context and handshake handler.

usingSystem;usingSystem.Text;usingNETCoreServer;namespaceSslChatServer{classChatSession:SslSession{publicChatSession(SslServerserver):base(server){}protectedoverridevoidOnConnected(){Console.WriteLine($"Chat SSL session with Id {Id} connected!");// Send invite messagestringmessage="Hello from SSL chat! Please send a message or '!' to disconnect the client!";Send(message);}protectedoverridevoidOnDisconnected(){Console.WriteLine($"Chat SSL session with Id {Id} disconnected!");}protectedoverridevoidOnReceived(byte[]buffer){stringmessage=Encoding.UTF8.GetString(buffer);Console.WriteLine("Incoming: "+message);// Multicast message to all connected sessionsServer.Multicast(message);// If the buffer starts with '!' the disconnect the current sessionif(message=="!")Disconnect();}protectedoverridevoidOnError(interror,stringcategory,stringmessage){Console.WriteLine($"Chat SSL session caught an error with code {error} and category '{category}': {message}");}}classChatServer:SslServer{publicChatServer(Serviceservice,SslContextcontext,InternetProtocolprotocol,intport):base(service,context,protocol,port){}protectedoverrideSslSessionCreateSession(){returnnewChatSession(this);}protectedoverridevoidOnError(interror,stringcategory,stringmessage){Console.WriteLine($"Chat SSL server caught an error with code {error} and category '{category}': {message}");}}classProgram{staticvoidMain(string[]args){// SSL server portintport=2222;if(args.Length>0)port=int.Parse(args[0]);Console.WriteLine($"SSL server port: {port}");// Create a new servicevarservice=newService();// Start the serviceConsole.Write("Service starting...");service.Start();Console.WriteLine("Done!");// Create and prepare a new SSL server contextvarcontext=newSslContext(SslMethod.TLSV12);context.SetPassword("qwerty");context.UseCertificateChainFile("../../../../Tools/certificates/server.pem");context.UsePrivateKeyFile("../../../../Tools/certificates/server.pem",SslFileFormat.PEM);context.UseTmpDHFile("../../../../Tools/certificates/dh4096.pem");// Create a new SSL chat servervarserver=newChatServer(service,context,InternetProtocol.IPv4,port);// Start the serverConsole.Write("Server starting...");server.Start();Console.WriteLine("Done!");Console.WriteLine("Press Enter to stop the server or '!' to restart the server...");// Perform text inputfor(;;){stringline=Console.ReadLine();if(line==String.Empty)break;// Restart the serverif(line=="!"){Console.Write("Server restarting...");server.Restart();Console.WriteLine("Done!");continue;}// Multicast admin message to all sessionsline="(admin) "+line;server.Multicast(line);}// Stop the serverConsole.Write("Server stopping...");server.Stop();Console.WriteLine("Done!");// Stop the serviceConsole.Write("Service stopping...");service.Stop();Console.WriteLine("Done!");}}}

Example: SSL chat client

Here comes the example of the SSL chat client. It connects to the SSL chat server and allows to send message to it and receive new messages.

This example is very similar to the TCP one except the code that prepares SSL context and handshake handler.

usingSystem;usingSystem.Text;usingSystem.Threading;usingNETCoreServer;namespaceSslChatClient{classChatClient:SslClient{publicChatClient(Serviceservice,SslContextcontext,stringaddress,intport):base(service,context,address,port){}publicvoidDisconnectAndStop(){_stop=true;Disconnect();while(IsConnected)Thread.Yield();}protectedoverridevoidOnConnected(){Console.WriteLine($"Chat SSL client connected a new session with Id {Id}");}protectedoverridevoidOnDisconnected(){Console.WriteLine($"Chat SSL client disconnected a session with Id {Id}");// Wait for a while...Thread.Sleep(1000);// Try to connect againif(!_stop)Connect();}protectedoverridevoidOnReceived(byte[]buffer){Console.WriteLine(Encoding.UTF8.GetString(buffer));}protectedoverridevoidOnError(interror,stringcategory,stringmessage){Console.WriteLine($"Chat SSL client caught an error with code {error} and category '{category}': {message}");}privatebool_stop;}classProgram{staticvoidMain(string[]args){// SSL server addressstringaddress="127.0.0.1";if(args.Length>0)address=args[0];// SSL server portintport=2222;if(args.Length>1)port=int.Parse(args[1]);Console.WriteLine($"SSL server address: {address}");Console.WriteLine($"SSL server port: {port}");// Create a new servicevarservice=newService();// Start the serviceConsole.Write("Service starting...");service.Start();Console.WriteLine("Done!");// Create and prepare a new SSL client contextvarcontext=newSslContext(SslMethod.TLSV12);context.SetVerifyMode(SslVerifyMode.VerifyPeer);context.LoadVerifyFile("../../../../Tools/certificates/ca.pem");// Create a new SSL chat clientvarclient=newChatClient(service,context,address,port);// Connect the clientConsole.Write("Client connecting...");client.Connect();Console.WriteLine("Done!");Console.WriteLine("Press Enter to stop the client or '!' to reconnect the client...");// Perform text inputfor(;;){stringline=Console.ReadLine();if(line==String.Empty)break;// Disconnect the clientif(line=="!"){Console.Write("Client disconnecting...");client.Disconnect();Console.WriteLine("Done!");continue;}// Send the entered text to the chat serverclient.Send(line);}// Disconnect the clientConsole.Write("Client disconnecting...");client.DisconnectAndStop();Console.WriteLine("Done!");// Stop the serviceConsole.Write("Service stopping...");service.Stop();Console.WriteLine("Done!");}}}

Example: UDP echo server

Here comes the example of the UDP echo server. It receives a datagram mesage from any UDP client and resend it back without any changes.

usingSystem;usingSystem.Text;usingNETCoreServer;namespaceUdpEchoServer{classEchoServer:UdpServer{publicEchoServer(Serviceservice,InternetProtocolprotocol,intport):base(service,protocol,port){}protectedoverridevoidOnReceived(UdpEndpointendpoint,byte[]buffer){Console.WriteLine("Incoming: "+Encoding.UTF8.GetString(buffer));// Echo the message back to the senderSend(endpoint,buffer);}protectedoverridevoidOnError(interror,stringcategory,stringmessage){Console.WriteLine($"Echo UDP server caught an error with code {error} and category '{category}': {message}");}}classProgram{staticvoidMain(string[]args){// UDP server portintport=3333;if(args.Length>0)port=int.Parse(args[0]);Console.WriteLine($"UDP server port: {port}");// Create a new servicevarservice=newService();// Start the serviceConsole.Write("Service starting...");service.Start();Console.WriteLine("Done!");// Create a new UDP echo servervarserver=newEchoServer(service,InternetProtocol.IPv4,port);// Start the serverConsole.Write("Server starting...");server.Start();Console.WriteLine("Done!");Console.WriteLine("Press Enter to stop the server or '!' to restart the server...");// Perform text inputfor(;;){stringline=Console.ReadLine();if(line==String.Empty)break;// Restart the serverif(line=="!"){Console.Write("Server restarting...");server.Restart();Console.WriteLine("Done!");}}// Stop the serverConsole.Write("Server stopping...");server.Stop();Console.WriteLine("Done!");// Stop the serviceConsole.Write("Service stopping...");service.Stop();Console.WriteLine("Done!");}}}

Example: UDP echo client

Here comes the example of the UDP echo client. It sends user datagram message to UDP server and listen for response.

usingSystem;usingSystem.Text;usingSystem.Threading;usingNETCoreServer;namespaceUdpEchoClient{classEchoClient:UdpClient{publicEchoClient(Serviceservice,stringaddress,intport):base(service,address,port){}publicvoidDisconnectAndStop(){_stop=true;Disconnect();while(IsConnected)Thread.Yield();}protectedoverridevoidOnConnected(){Console.WriteLine($"Echo UDP client connected a new session with Id {Id}");}protectedoverridevoidOnDisconnected(){Console.WriteLine($"Echo UDP client disconnected a session with Id {Id}");// Wait for a while...Thread.Sleep(1000);// Try to connect againif(!_stop)Connect();}protectedoverridevoidOnReceived(UdpEndpointendpoint,byte[]buffer){Console.WriteLine("Incoming: "+Encoding.UTF8.GetString(buffer));}protectedoverridevoidOnError(interror,stringcategory,stringmessage){Console.WriteLine($"Echo UDP client caught an error with code {error} and category '{category}': {message}");}privatebool_stop;}classProgram{staticvoidMain(string[]args){// UDP server addressstringaddress="127.0.0.1";if(args.Length>0)address=args[0];// UDP server portintport=3333;if(args.Length>1)port=int.Parse(args[1]);Console.WriteLine($"UDP server address: {address}");Console.WriteLine($"UDP server port: {port}");// Create a new servicevarservice=newService();// Start the serviceConsole.Write("Service starting...");service.Start();Console.WriteLine("Done!");// Create a new TCP chat clientvarclient=newEchoClient(service,address,port);// Connect the clientConsole.Write("Client connecting...");client.Connect();Console.WriteLine("Done!");Console.WriteLine("Press Enter to stop the client or '!' to reconnect the client...");// Perform text inputfor(;;){stringline=Console.ReadLine();if(line==String.Empty)break;// Disconnect the clientif(line=="!"){Console.Write("Client disconnecting...");client.Disconnect();Console.WriteLine("Done!");continue;}// Send the entered text to the chat serverclient.Send(line);}// Disconnect the clientConsole.Write("Client disconnecting...");client.DisconnectAndStop();Console.WriteLine("Done!");// Stop the serviceConsole.Write("Service stopping...");service.Stop();Console.WriteLine("Done!");}}}

Example: UDP multicast server

Here comes the example of the UDP multicast server. It use multicast IP address to multicast datagram messages to all client that joined corresponding UDP multicast group.

usingSystem;usingSystem.Text;usingNETCoreServer;namespaceUdpMulticastServer{classMulticastServer:UdpServer{publicMulticastServer(Serviceservice,InternetProtocolprotocol,intport):base(service,protocol,port){}protectedoverridevoidOnError(interror,stringcategory,stringmessage){Console.WriteLine($"Multicast UDP server caught an error with code {error} and category '{category}': {message}");}}classProgram{staticvoidMain(string[]args){// UDP multicast addressstringmulticastAddress="239.255.0.1";if(args.Length>0)multicastAddress=args[0];// UDP multicast portintmulticastPort=3334;if(args.Length>1)multicastPort=int.Parse(args[1]);Console.WriteLine($"UDP multicast address: {multicastAddress}");Console.WriteLine($"UDP multicast port: {multicastPort}");// Create a new servicevarservice=newService();// Start the serviceConsole.Write("Service starting...");service.Start();Console.WriteLine("Done!");// Create a new UDP multicast servervarserver=newMulticastServer(service,InternetProtocol.IPv4,0);// Start the multicast serverConsole.Write("Server starting...");server.Start(multicastAddress,multicastPort);Console.WriteLine("Done!");Console.WriteLine("Press Enter to stop the server or '!' to restart the server...");// Perform text inputfor(;;){stringline=Console.ReadLine();if(line==String.Empty)break;// Restart the serverif(line=="!"){Console.Write("Server restarting...");server.Restart();Console.WriteLine("Done!");continue;}// Multicast admin message to all sessionsline="(admin) "+line;server.Multicast(line);}// Stop the serverConsole.Write("Server stopping...");server.Stop();Console.WriteLine("Done!");// Stop the serviceConsole.Write("Service stopping...");service.Stop();Console.WriteLine("Done!");}}}

Example: UDP multicast client

Here comes the example of the UDP multicast client. It use multicast IP address and joins UDP multicast group in order to receive multicasted datagram messages from UDP server.

usingSystem;usingSystem.Text;usingSystem.Threading;usingNETCoreServer;namespaceUdpMulticastClient{classMulticastClient:UdpClient{publicstringMulticast;publicMulticastClient(Serviceservice,stringaddress,intport):base(service,address,port){}publicvoidDisconnectAndStop(){_stop=true;Disconnect();while(IsConnected)Thread.Yield();}protectedoverridevoidOnConnected(){Console.WriteLine($"Multicast UDP client connected a new session with Id {Id}");// Join UDP multicast groupJoinMulticastGroup(Multicast);}protectedoverridevoidOnDisconnected(){Console.WriteLine($"Multicast UDP client disconnected a session with Id {Id}");// Wait for a while...Thread.Sleep(1000);// Try to connect againif(!_stop)Connect();}protectedoverridevoidOnReceived(UdpEndpointendpoint,byte[]buffer){Console.WriteLine("Incoming: "+Encoding.UTF8.GetString(buffer));}protectedoverridevoidOnError(interror,stringcategory,stringmessage){Console.WriteLine($"Multicast UDP client caught an error with code {error} and category '{category}': {message}");}privatebool_stop;}classProgram{staticvoidMain(string[]args){// UDP listen addressstringlistenAddress="0.0.0.0";if(args.Length>0)listenAddress=args[0];// UDP multicast addressstringmulticastAddress="239.255.0.1";if(args.Length>1)multicastAddress=args[1];// UDP multicast portintmulticastPort=3334;if(args.Length>2)multicastPort=int.Parse(args[2]);Console.WriteLine($"UDP listen address: {listenAddress}");Console.WriteLine($"UDP multicast address: {multicastAddress}");Console.WriteLine($"UDP multicast port: {multicastPort}");// Create a new servicevarservice=newService();// Start the serviceConsole.Write("Service starting...");service.Start();Console.WriteLine("Done!");// Create a new TCP chat clientvarclient=newMulticastClient(service,listenAddress,multicastPort);client.SetupMulticast(true);client.Multicast=multicastAddress;// Connect the clientConsole.Write("Client connecting...");client.Connect();Console.WriteLine("Done!");Console.WriteLine("Press Enter to stop the client or '!' to reconnect the client...");// Perform text inputfor(;;){stringline=Console.ReadLine();if(line==String.Empty)break;// Disconnect the clientif(line=="!"){Console.Write("Client disconnecting...");client.Disconnect();Console.WriteLine("Done!");continue;}// Send the entered text to the chat serverclient.Send(line);}// Disconnect the clientConsole.Write("Client disconnecting...");client.DisconnectAndStop();Console.WriteLine("Done!");// Stop the serviceConsole.Write("Service stopping...");service.Stop();Console.WriteLine("Done!");}}}

Performance

Here comes several communication scenarios with timing measurements.

Benchmark environment is the following:

CPU architecutre: Intel(R) Core(TM) i7-4790K CPU @ 4.00GHz
CPU logical cores: 8
CPU physical cores: 4
CPU clock speed: 3.998 GHz
CPU Hyper-Threading: enabled
RAM total: 31.962 GiB
RAM free: 21.623 GiB
OS version: Microsoft Windows 8 Enterprise Edition (build 9200), 64-bit
OS bits: 64-bit
Process bits: 64-bit
Process configuaraion: release

Benchmark: Round-Trip

Round-trip

This scenario sends lots of messages from several clients to a server. The server responses to each message and resend the similar response to the client. The benchmark measures total Round-trip time to send all messages and receive all responses, messages & data throughput, count of errors.

TCP echo server

Server address: 127.0.0.1
Server port: 1111
Working threads: 1
Working clients: 1
Messages to send: 1000000
Message size: 32
Errors: 0
Round-trip time: 3.893 s
Total data: 30.530 MiB
Total messages: 1000000
Data throughput: 7.858 MiB/s
Message latency: 3.893 mcs
Message throughput: 256842 msg/s
Server address: 127.0.0.1
Server port: 1111
Working threads: 4
Working clients: 100
Messages to send: 1000000
Message size: 32
Errors: 0
Round-trip time: 1.557 s
Total data: 30.518 MiB
Total messages: 999632
Data throughput: 19.597 MiB/s
Message latency: 1.558 mcs
Message throughput: 641705 msg/s

SSL echo server

Server address: 127.0.0.1
Server port: 2222
Working threads: 1
Working clients: 1
Messages to send: 1000000
Message size: 32
Errors: 0
Round-trip time: 7.201 s
Total data: 30.530 MiB
Total messages: 1000000
Data throughput: 4.243 MiB/s
Message latency: 7.201 mcs
Message throughput: 138858 msg/s
Server address: 127.0.0.1
Server port: 2222
Working threads: 4
Working clients: 100
Messages to send: 1000000
Message size: 32
Errors: 0
Round-trip time: 4.365 s
Total data: 30.328 MiB
Total messages: 993547
Data throughput: 6.968 MiB/s
Message latency: 4.393 mcs
Message throughput: 227600 msg/s

UDP echo server

Server address: 127.0.0.1
Server port: 3333
Working threads: 1
Working clients: 1
Messages to send: 1000000
Message size: 32
Errors: 0
Round-trip time: 22.071 s
Total data: 30.530 MiB
Total messages: 1000000
Data throughput: 1.391 MiB/s
Message latency: 22.071 mcs
Message throughput: 45306 msg/s
Server address: 127.0.0.1
Server port: 3333
Working threads: 4
Working clients: 100
Messages to send: 1000000
Message size: 32
Errors: 0
Round-trip time: 6.086 s
Total data: 30.512 MiB
Total messages: 999471
Data throughput: 5.011 MiB/s
Message latency: 6.090 mcs
Message throughput: 164201 msg/s

Benchmark: Multicast

Multicast

In this scenario server multicasts messages to all connected clients. The benchmark counts total messages received by all clients for all the working time and measures messages & data throughput, count of errors.

TCP multicast server

Server address: 127.0.0.1
Server port: 1111
Working threads: 1
Working clients: 1
Message size: 32
Errors: 0
Multicast time: 10.002 s
Total data: 970.554 MiB
Total messages: 31802690
Data throughput: 97.027 MiB/s
Message latency: 314 ns
Message throughput: 3179388 msg/s
Server address: 127.0.0.1
Server port: 1111
Working threads: 4
Working clients: 100
Message size: 32
Errors: 0
Multicast time: 10.007 s
Total data: 3.442 GiB
Total messages: 115147638
Data throughput: 351.135 MiB/s
Message latency: 86 ns
Message throughput: 11505891 msg/s

SSL multicast server

Server address: 127.0.0.1
Server port: 2222
Working threads: 1
Working clients: 1
Message size: 32
Errors: 0
Multicast time: 10.011 s
Total data: 458.031 MiB
Total messages: 15008762
Data throughput: 45.769 MiB/s
Message latency: 667 ns
Message throughput: 1499196 msg/s
Server address: 127.0.0.1
Server port: 2222
Working threads: 4
Working clients: 100
Message size: 32
Errors: 0
Multicast time: 10.350 s
Total data: 3.082 GiB
Total messages: 103351505
Data throughput: 304.726 MiB/s
Message latency: 100 ns
Message throughput: 9984724 msg/s

UDP multicast server

Server address: 239.255.0.1
Server port: 3333
Working threads: 1
Working clients: 1
Message size: 32
Errors: 0
Multicast time: 10.004 s
Total data: 19.644 MiB
Total messages: 643205
Data throughput: 1.985 MiB/s
Message latency: 15.553 mcs
Message throughput: 64292 msg/s
Server address: 239.255.0.1
Server port: 3333
Working threads: 4
Working clients: 100
Message size: 32
Errors: 0
Multicast time: 10.007 s
Total data: 78.498 MiB
Total messages: 2571847
Data throughput: 7.862 MiB/s
Message latency: 3.891 mcs
Message throughput: 256982 msg/s

OpenSSL certificates

In order to create OpenSSL based server and client you should prepare a set of SSL certificates. Here comes several steps to get a self-signed set of SSL certificates for testing purposes:

Certificate Authority

  • Create CA private key
openssl genrsa -des3 -passout pass:qwerty -out ca-secret.key 4096
  • Remove passphrase
openssl rsa -passin pass:qwerty -in ca-secret.key -out ca.key
  • Create CA self-signed certificate
openssl req -new -x509 -days 3650 -subj '/C=BY/ST=Belarus/L=Minsk/O=Example root CA/OU=Example CA unit/CN=example.com' -key ca.key -out ca.crt -config openssl.cfg
  • Convert CA self-signed certificate to PKCS
openssl pkcs12 -clcerts -export -passout pass:qwerty -in ca.crt -inkey ca.key -out ca.p12
  • Convert CA self-signed certificate to PEM
openssl pkcs12 -clcerts -passin pass:qwerty -passout pass:qwerty -in ca.p12 -out ca.pem

SSL Server certificate

  • Create private key for the server
openssl genrsa -des3 -passout pass:qwerty -out server-secret.key 4096
  • Remove passphrase
openssl rsa -passin pass:qwerty -in server-secret.key -out server.key
  • Create CSR for the server
openssl req -new -subj '/C=BY/ST=Belarus/L=Minsk/O=Example server/OU=Example server unit/CN=server.example.com' -key server.key -out server.csr -config openssl.cfg
  • Create certificate for the server
openssl x509 -req -days 3650 -in server.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out server.crt
  • Convert the server certificate to PKCS
openssl pkcs12 -clcerts -export -passout pass:qwerty -in server.crt -inkey server.key -out server.p12
  • Convert the server certificate to PEM
openssl pkcs12 -clcerts -passin pass:qwerty -passout pass:qwerty -in server.p12 -out server.pem

SSL Client certificate

  • Create private key for the client
openssl genrsa -des3 -passout pass:qwerty -out client-secret.key 4096
  • Remove passphrase
openssl rsa -passin pass:qwerty -in client-secret.key -out client.key
  • Create CSR for the client
openssl req -new -subj '/C=BY/ST=Belarus/L=Minsk/O=Example client/OU=Example client unit/CN=client.example.com' -key client.key -out client.csr -config openssl.cfg
  • Create the client certificate
openssl x509 -req -days 3650 -in client.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out client.crt
  • Convert the client certificate to PKCS
openssl pkcs12 -clcerts -export -passout pass:qwerty -in client.crt -inkey client.key -out client.p12
  • Convert the client certificate to PEM
openssl pkcs12 -clcerts -passin pass:qwerty -passout pass:qwerty -in client.p12 -out client.pem

Diffie-Hellman key exchange

  • Create DH parameters
openssl dhparam -out dh4096.pem 4096

About

Ultra fast and low latency asynchronous socket server & client C# .NET Core library with support TCP, SSL, UDP protocols and 10K connections problem solution

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

NETCoreServer

Windows build status

Ultra fast and low latency asynchronous socket server & client C# .NET Core library with support TCP, SSL, UDP protocols and 10K connections problem solution.

NETCoreServer documentation
NETCoreServer downloads

Contents

Features

Requirements

How to build?

Setup repository

git clone https://github.com/chronoxor/NETCoreServer.git
cd NETCoreServer

Windows (Visual Studio)

Open and build NETCoreServer.sln or run the build script:

cd build
vs.bat

The build script will create "release" directory with zip files:

  • NETCoreServer.zip - C# Server assembly
  • Benchmarks.zip - C# Server benchmarks
  • Examples.zip - C# Server examples

Examples

Example: Asio timer

Here comes the example of Asio timer. It can be used to wait for some action in future with providing absolute time or relative time span. Asio timer can be used in synchronous or asynchronous modes.

usingSystem;usingSystem.Threading;usingNETCoreServer;namespaceAsioTimer{classAsioTimer:Timer{publicAsioTimer(Serviceservice):base(service){}protectedoverridevoidOnTimer(boolcanceled){Console.WriteLine("Asio timer "+(canceled?"canceled":"expired"));}protectedoverridevoidOnError(interror,stringcategory,stringmessage){Console.WriteLine($"Asio timer caught an error with code {error} and category '{category}': {message}");}}classProgram{staticvoidMain(){// Create a new servicevarservice=newService();// Start the serviceConsole.Write("Service starting...");service.Start();Console.WriteLine("Done!");// Create a new Asio timervartimer=newAsioTimer(service);// Setup and synchronously wait for the timertimer.Setup(DateTime.UtcNow.AddSeconds(1));timer.WaitSync();// Setup and asynchronously wait for the timertimer.Setup(TimeSpan.FromSeconds(1));timer.WaitAsync();// Wait for a while...Thread.Sleep(2000);// Setup and asynchronously wait for the timertimer.Setup(TimeSpan.FromSeconds(1));timer.WaitAsync();// Wait for a while...Thread.Sleep(500);// Cancel the timertimer.Cancel();// Wait for a while...Thread.Sleep(500);// Stop the serviceConsole.Write("Service stopping...");service.Stop();Console.WriteLine("Done!");}}}

Output of the above example is the following:

Service starting...Done!
Asio timer expired
Asio timer canceled
Service stopping...Done!

Example: TCP chat server

Here comes the example of the TCP chat server. It handles multiple TCP client sessions and multicast received message from any session to all ones. Also it is possible to send admin message directly from the server.

usingSystem;usingSystem.Text;usingNETCoreServer;namespaceTcpChatServer{classChatSession:TcpSession{publicChatSession(TcpServerserver):base(server){}protectedoverridevoidOnConnected(){Console.WriteLine($"Chat TCP session with Id {Id} connected!");// Send invite messagestringmessage="Hello from TCP chat! Please send a message or '!' to disconnect the client!";Send(message);}protectedoverridevoidOnDisconnected(){Console.WriteLine($"Chat TCP session with Id {Id} disconnected!");}protectedoverridevoidOnReceived(byte[]buffer){stringmessage=Encoding.UTF8.GetString(buffer);Console.WriteLine("Incoming: "+message);// Multicast message to all connected sessionsServer.Multicast(message);// If the buffer starts with '!' the disconnect the current sessionif(message=="!")Disconnect();}protectedoverridevoidOnError(interror,stringcategory,stringmessage){Console.WriteLine($"Chat TCP session caught an error with code {error} and category '{category}': {message}");}}classChatServer:TcpServer{publicChatServer(Serviceservice,InternetProtocolprotocol,intport):base(service,protocol,port){}protectedoverrideTcpSessionCreateSession(){returnnewChatSession(this);}protectedoverridevoidOnError(interror,stringcategory,stringmessage){Console.WriteLine($"Chat TCP server caught an error with code {error} and category '{category}': {message}");}}classProgram{staticvoidMain(string[]args){// TCP server portintport=1111;if(args.Length>0)port=int.Parse(args[0]);Console.WriteLine($"TCP server port: {port}");// Create a new servicevarservice=newService();// Start the serviceConsole.Write("Service starting...");service.Start();Console.WriteLine("Done!");// Create a new TCP chat servervarserver=newChatServer(service,InternetProtocol.IPv4,port);// Start the serverConsole.Write("Server starting...");server.Start();Console.WriteLine("Done!");Console.WriteLine("Press Enter to stop the server or '!' to restart the server...");// Perform text inputfor(;;){stringline=Console.ReadLine();if(line==String.Empty)break;// Restart the serverif(line=="!"){Console.Write("Server restarting...");server.Restart();Console.WriteLine("Done!");continue;}// Multicast admin message to all sessionsline="(admin) "+line;server.Multicast(line);}// Stop the serverConsole.Write("Server stopping...");server.Stop();Console.WriteLine("Done!");// Stop the serviceConsole.Write("Service stopping...");service.Stop();Console.WriteLine("Done!");}}}

Example: TCP chat client

Here comes the example of the TCP chat client. It connects to the TCP chat server and allows to send message to it and receive new messages.

usingSystem;usingSystem.Text;usingSystem.Threading;usingNETCoreServer;namespaceTcpChatClient{classChatClient:TcpClient{publicChatClient(Serviceservice,stringaddress,intport):base(service,address,port){}publicvoidDisconnectAndStop(){_stop=true;Disconnect();while(IsConnected)Thread.Yield();}protectedoverridevoidOnConnected(){Console.WriteLine($"Chat TCP client connected a new session with Id {Id}");}protectedoverridevoidOnDisconnected(){Console.WriteLine($"Chat TCP client disconnected a session with Id {Id}");// Wait for a while...Thread.Sleep(1000);// Try to connect againif(!_stop)Connect();}protectedoverridevoidOnReceived(byte[]buffer){Console.WriteLine(Encoding.UTF8.GetString(buffer));}protectedoverridevoidOnError(interror,stringcategory,stringmessage){Console.WriteLine($"Chat TCP client caught an error with code {error} and category '{category}': {message}");}privatebool_stop;}classProgram{staticvoidMain(string[]args){// TCP server addressstringaddress="127.0.0.1";if(args.Length>0)address=args[0];// TCP server portintport=1111;if(args.Length>1)port=int.Parse(args[1]);Console.WriteLine($"TCP server address: {address}");Console.WriteLine($"TCP server port: {port}");// Create a new servicevarservice=newService();// Start the serviceConsole.Write("Service starting...");service.Start();Console.WriteLine("Done!");// Create a new TCP chat clientvarclient=newChatClient(service,address,port);// Connect the clientConsole.Write("Client connecting...");client.Connect();Console.WriteLine("Done!");Console.WriteLine("Press Enter to stop the client or '!' to reconnect the client...");// Perform text inputfor(;;){stringline=Console.ReadLine();if(line==String.Empty)break;// Disconnect the clientif(line=="!"){Console.Write("Client disconnecting...");client.Disconnect();Console.WriteLine("Done!");continue;}// Send the entered text to the chat serverclient.Send(line);}// Disconnect the clientConsole.Write("Client disconnecting...");client.DisconnectAndStop();Console.WriteLine("Done!");// Stop the serviceConsole.Write("Service stopping...");service.Stop();Console.WriteLine("Done!");}}}

Example: SSL chat server

Here comes the example of the SSL chat server. It handles multiple SSL client sessions and multicast received message from any session to all ones. Also it is possible to send admin message directly from the server.

This example is very similar to the TCP one except the code that prepares SSL context and handshake handler.

usingSystem;usingSystem.Text;usingNETCoreServer;namespaceSslChatServer{classChatSession:SslSession{publicChatSession(SslServerserver):base(server){}protectedoverridevoidOnConnected(){Console.WriteLine($"Chat SSL session with Id {Id} connected!");// Send invite messagestringmessage="Hello from SSL chat! Please send a message or '!' to disconnect the client!";Send(message);}protectedoverridevoidOnDisconnected(){Console.WriteLine($"Chat SSL session with Id {Id} disconnected!");}protectedoverridevoidOnReceived(byte[]buffer){stringmessage=Encoding.UTF8.GetString(buffer);Console.WriteLine("Incoming: "+message);// Multicast message to all connected sessionsServer.Multicast(message);// If the buffer starts with '!' the disconnect the current sessionif(message=="!")Disconnect();}protectedoverridevoidOnError(interror,stringcategory,stringmessage){Console.WriteLine($"Chat SSL session caught an error with code {error} and category '{category}': {message}");}}classChatServer:SslServer{publicChatServer(Serviceservice,SslContextcontext,InternetProtocolprotocol,intport):base(service,context,protocol,port){}protectedoverrideSslSessionCreateSession(){returnnewChatSession(this);}protectedoverridevoidOnError(interror,stringcategory,stringmessage){Console.WriteLine($"Chat SSL server caught an error with code {error} and category '{category}': {message}");}}classProgram{staticvoidMain(string[]args){// SSL server portintport=2222;if(args.Length>0)port=int.Parse(args[0]);Console.WriteLine($"SSL server port: {port}");// Create a new servicevarservice=newService();// Start the serviceConsole.Write("Service starting...");service.Start();Console.WriteLine("Done!");// Create and prepare a new SSL server contextvarcontext=newSslContext(SslMethod.TLSV12);context.SetPassword("qwerty");context.UseCertificateChainFile("../../../../Tools/certificates/server.pem");context.UsePrivateKeyFile("../../../../Tools/certificates/server.pem",SslFileFormat.PEM);context.UseTmpDHFile("../../../../Tools/certificates/dh4096.pem");// Create a new SSL chat servervarserver=newChatServer(service,context,InternetProtocol.IPv4,port);// Start the serverConsole.Write("Server starting...");server.Start();Console.WriteLine("Done!");Console.WriteLine("Press Enter to stop the server or '!' to restart the server...");// Perform text inputfor(;;){stringline=Console.ReadLine();if(line==String.Empty)break;// Restart the serverif(line=="!"){Console.Write("Server restarting...");server.Restart();Console.WriteLine("Done!");continue;}// Multicast admin message to all sessionsline="(admin) "+line;server.Multicast(line);}// Stop the serverConsole.Write("Server stopping...");server.Stop();Console.WriteLine("Done!");// Stop the serviceConsole.Write("Service stopping...");service.Stop();Console.WriteLine("Done!");}}}

Example: SSL chat client

Here comes the example of the SSL chat client. It connects to the SSL chat server and allows to send message to it and receive new messages.

This example is very similar to the TCP one except the code that prepares SSL context and handshake handler.

usingSystem;usingSystem.Text;usingSystem.Threading;usingNETCoreServer;namespaceSslChatClient{classChatClient:SslClient{publicChatClient(Serviceservice,SslContextcontext,stringaddress,intport):base(service,context,address,port){}publicvoidDisconnectAndStop(){_stop=true;Disconnect();while(IsConnected)Thread.Yield();}protectedoverridevoidOnConnected(){Console.WriteLine($"Chat SSL client connected a new session with Id {Id}");}protectedoverridevoidOnDisconnected(){Console.WriteLine($"Chat SSL client disconnected a session with Id {Id}");// Wait for a while...Thread.Sleep(1000);// Try to connect againif(!_stop)Connect();}protectedoverridevoidOnReceived(byte[]buffer){Console.WriteLine(Encoding.UTF8.GetString(buffer));}protectedoverridevoidOnError(interror,stringcategory,stringmessage){Console.WriteLine($"Chat SSL client caught an error with code {error} and category '{category}': {message}");}privatebool_stop;}classProgram{staticvoidMain(string[]args){// SSL server addressstringaddress="127.0.0.1";if(args.Length>0)address=args[0];// SSL server portintport=2222;if(args.Length>1)port=int.Parse(args[1]);Console.WriteLine($"SSL server address: {address}");Console.WriteLine($"SSL server port: {port}");// Create a new servicevarservice=newService();// Start the serviceConsole.Write("Service starting...");service.Start();Console.WriteLine("Done!");// Create and prepare a new SSL client contextvarcontext=newSslContext(SslMethod.TLSV12);context.SetVerifyMode(SslVerifyMode.VerifyPeer);context.LoadVerifyFile("../../../../Tools/certificates/ca.pem");// Create a new SSL chat clientvarclient=newChatClient(service,context,address,port);// Connect the clientConsole.Write("Client connecting...");client.Connect();Console.WriteLine("Done!");Console.WriteLine("Press Enter to stop the client or '!' to reconnect the client...");// Perform text inputfor(;;){stringline=Console.ReadLine();if(line==String.Empty)break;// Disconnect the clientif(line=="!"){Console.Write("Client disconnecting...");client.Disconnect();Console.WriteLine("Done!");continue;}// Send the entered text to the chat serverclient.Send(line);}// Disconnect the clientConsole.Write("Client disconnecting...");client.DisconnectAndStop();Console.WriteLine("Done!");// Stop the serviceConsole.Write("Service stopping...");service.Stop();Console.WriteLine("Done!");}}}

Example: UDP echo server

Here comes the example of the UDP echo server. It receives a datagram mesage from any UDP client and resend it back without any changes.

usingSystem;usingSystem.Text;usingNETCoreServer;namespaceUdpEchoServer{classEchoServer:UdpServer{publicEchoServer(Serviceservice,InternetProtocolprotocol,intport):base(service,protocol,port){}protectedoverridevoidOnReceived(UdpEndpointendpoint,byte[]buffer){Console.WriteLine("Incoming: "+Encoding.UTF8.GetString(buffer));// Echo the message back to the senderSend(endpoint,buffer);}protectedoverridevoidOnError(interror,stringcategory,stringmessage){Console.WriteLine($"Echo UDP server caught an error with code {error} and category '{category}': {message}");}}classProgram{staticvoidMain(string[]args){// UDP server portintport=3333;if(args.Length>0)port=int.Parse(args[0]);Console.WriteLine($"UDP server port: {port}");// Create a new servicevarservice=newService();// Start the serviceConsole.Write("Service starting...");service.Start();Console.WriteLine("Done!");// Create a new UDP echo servervarserver=newEchoServer(service,InternetProtocol.IPv4,port);// Start the serverConsole.Write("Server starting...");server.Start();Console.WriteLine("Done!");Console.WriteLine("Press Enter to stop the server or '!' to restart the server...");// Perform text inputfor(;;){stringline=Console.ReadLine();if(line==String.Empty)break;// Restart the serverif(line=="!"){Console.Write("Server restarting...");server.Restart();Console.WriteLine("Done!");}}// Stop the serverConsole.Write("Server stopping...");server.Stop();Console.WriteLine("Done!");// Stop the serviceConsole.Write("Service stopping...");service.Stop();Console.WriteLine("Done!");}}}

Example: UDP echo client

Here comes the example of the UDP echo client. It sends user datagram message to UDP server and listen for response.

usingSystem;usingSystem.Text;usingSystem.Threading;usingNETCoreServer;namespaceUdpEchoClient{classEchoClient:UdpClient{publicEchoClient(Serviceservice,stringaddress,intport):base(service,address,port){}publicvoidDisconnectAndStop(){_stop=true;Disconnect();while(IsConnected)Thread.Yield();}protectedoverridevoidOnConnected(){Console.WriteLine($"Echo UDP client connected a new session with Id {Id}");}protectedoverridevoidOnDisconnected(){Console.WriteLine($"Echo UDP client disconnected a session with Id {Id}");// Wait for a while...Thread.Sleep(1000);// Try to connect againif(!_stop)Connect();}protectedoverridevoidOnReceived(UdpEndpointendpoint,byte[]buffer){Console.WriteLine("Incoming: "+Encoding.UTF8.GetString(buffer));}protectedoverridevoidOnError(interror,stringcategory,stringmessage){Console.WriteLine($"Echo UDP client caught an error with code {error} and category '{category}': {message}");}privatebool_stop;}classProgram{staticvoidMain(string[]args){// UDP server addressstringaddress="127.0.0.1";if(args.Length>0)address=args[0];// UDP server portintport=3333;if(args.Length>1)port=int.Parse(args[1]);Console.WriteLine($"UDP server address: {address}");Console.WriteLine($"UDP server port: {port}");// Create a new servicevarservice=newService();// Start the serviceConsole.Write("Service starting...");service.Start();Console.WriteLine("Done!");// Create a new TCP chat clientvarclient=newEchoClient(service,address,port);// Connect the clientConsole.Write("Client connecting...");client.Connect();Console.WriteLine("Done!");Console.WriteLine("Press Enter to stop the client or '!' to reconnect the client...");// Perform text inputfor(;;){stringline=Console.ReadLine();if(line==String.Empty)break;// Disconnect the clientif(line=="!"){Console.Write("Client disconnecting...");client.Disconnect();Console.WriteLine("Done!");continue;}// Send the entered text to the chat serverclient.Send(line);}// Disconnect the clientConsole.Write("Client disconnecting...");client.DisconnectAndStop();Console.WriteLine("Done!");// Stop the serviceConsole.Write("Service stopping...");service.Stop();Console.WriteLine("Done!");}}}

Example: UDP multicast server

Here comes the example of the UDP multicast server. It use multicast IP address to multicast datagram messages to all client that joined corresponding UDP multicast group.

usingSystem;usingSystem.Text;usingNETCoreServer;namespaceUdpMulticastServer{classMulticastServer:UdpServer{publicMulticastServer(Serviceservice,InternetProtocolprotocol,intport):base(service,protocol,port){}protectedoverridevoidOnError(interror,stringcategory,stringmessage){Console.WriteLine($"Multicast UDP server caught an error with code {error} and category '{category}': {message}");}}classProgram{staticvoidMain(string[]args){// UDP multicast addressstringmulticastAddress="239.255.0.1";if(args.Length>0)multicastAddress=args[0];// UDP multicast portintmulticastPort=3334;if(args.Length>1)multicastPort=int.Parse(args[1]);Console.WriteLine($"UDP multicast address: {multicastAddress}");Console.WriteLine($"UDP multicast port: {multicastPort}");// Create a new servicevarservice=newService();// Start the serviceConsole.Write("Service starting...");service.Start();Console.WriteLine("Done!");// Create a new UDP multicast servervarserver=newMulticastServer(service,InternetProtocol.IPv4,0);// Start the multicast serverConsole.Write("Server starting...");server.Start(multicastAddress,multicastPort);Console.WriteLine("Done!");Console.WriteLine("Press Enter to stop the server or '!' to restart the server...");// Perform text inputfor(;;){stringline=Console.ReadLine();if(line==String.Empty)break;// Restart the serverif(line=="!"){Console.Write("Server restarting...");server.Restart();Console.WriteLine("Done!");continue;}// Multicast admin message to all sessionsline="(admin) "+line;server.Multicast(line);}// Stop the serverConsole.Write("Server stopping...");server.Stop();Console.WriteLine("Done!");// Stop the serviceConsole.Write("Service stopping...");service.Stop();Console.WriteLine("Done!");}}}

Example: UDP multicast client

Here comes the example of the UDP multicast client. It use multicast IP address and joins UDP multicast group in order to receive multicasted datagram messages from UDP server.

usingSystem;usingSystem.Text;usingSystem.Threading;usingNETCoreServer;namespaceUdpMulticastClient{classMulticastClient:UdpClient{publicstringMulticast;publicMulticastClient(Serviceservice,stringaddress,intport):base(service,address,port){}publicvoidDisconnectAndStop(){_stop=true;Disconnect();while(IsConnected)Thread.Yield();}protectedoverridevoidOnConnected(){Console.WriteLine($"Multicast UDP client connected a new session with Id {Id}");// Join UDP multicast groupJoinMulticastGroup(Multicast);}protectedoverridevoidOnDisconnected(){Console.WriteLine($"Multicast UDP client disconnected a session with Id {Id}");// Wait for a while...Thread.Sleep(1000);// Try to connect againif(!_stop)Connect();}protectedoverridevoidOnReceived(UdpEndpointendpoint,byte[]buffer){Console.WriteLine("Incoming: "+Encoding.UTF8.GetString(buffer));}protectedoverridevoidOnError(interror,stringcategory,stringmessage){Console.WriteLine($"Multicast UDP client caught an error with code {error} and category '{category}': {message}");}privatebool_stop;}classProgram{staticvoidMain(string[]args){// UDP listen addressstringlistenAddress="0.0.0.0";if(args.Length>0)listenAddress=args[0];// UDP multicast addressstringmulticastAddress="239.255.0.1";if(args.Length>1)multicastAddress=args[1];// UDP multicast portintmulticastPort=3334;if(args.Length>2)multicastPort=int.Parse(args[2]);Console.WriteLine($"UDP listen address: {listenAddress}");Console.WriteLine($"UDP multicast address: {multicastAddress}");Console.WriteLine($"UDP multicast port: {multicastPort}");// Create a new servicevarservice=newService();// Start the serviceConsole.Write("Service starting...");service.Start();Console.WriteLine("Done!");// Create a new TCP chat clientvarclient=newMulticastClient(service,listenAddress,multicastPort);client.SetupMulticast(true);client.Multicast=multicastAddress;// Connect the clientConsole.Write("Client connecting...");client.Connect();Console.WriteLine("Done!");Console.WriteLine("Press Enter to stop the client or '!' to reconnect the client...");// Perform text inputfor(;;){stringline=Console.ReadLine();if(line==String.Empty)break;// Disconnect the clientif(line=="!"){Console.Write("Client disconnecting...");client.Disconnect();Console.WriteLine("Done!");continue;}// Send the entered text to the chat serverclient.Send(line);}// Disconnect the clientConsole.Write("Client disconnecting...");client.DisconnectAndStop();Console.WriteLine("Done!");// Stop the serviceConsole.Write("Service stopping...");service.Stop();Console.WriteLine("Done!");}}}

Performance

Here comes several communication scenarios with timing measurements.

Benchmark environment is the following:

CPU architecutre: Intel(R) Core(TM) i7-4790K CPU @ 4.00GHz
CPU logical cores: 8
CPU physical cores: 4
CPU clock speed: 3.998 GHz
CPU Hyper-Threading: enabled
RAM total: 31.962 GiB
RAM free: 21.623 GiB
OS version: Microsoft Windows 8 Enterprise Edition (build 9200), 64-bit
OS bits: 64-bit
Process bits: 64-bit
Process configuaraion: release

Benchmark: Round-Trip

Round-trip

This scenario sends lots of messages from several clients to a server. The server responses to each message and resend the similar response to the client. The benchmark measures total Round-trip time to send all messages and receive all responses, messages & data throughput, count of errors.

TCP echo server

Server address: 127.0.0.1
Server port: 1111
Working threads: 1
Working clients: 1
Messages to send: 1000000
Message size: 32
Errors: 0
Round-trip time: 3.893 s
Total data: 30.530 MiB
Total messages: 1000000
Data throughput: 7.858 MiB/s
Message latency: 3.893 mcs
Message throughput: 256842 msg/s
Server address: 127.0.0.1
Server port: 1111
Working threads: 4
Working clients: 100
Messages to send: 1000000
Message size: 32
Errors: 0
Round-trip time: 1.557 s
Total data: 30.518 MiB
Total messages: 999632
Data throughput: 19.597 MiB/s
Message latency: 1.558 mcs
Message throughput: 641705 msg/s

SSL echo server

Server address: 127.0.0.1
Server port: 2222
Working threads: 1
Working clients: 1
Messages to send: 1000000
Message size: 32
Errors: 0
Round-trip time: 7.201 s
Total data: 30.530 MiB
Total messages: 1000000
Data throughput: 4.243 MiB/s
Message latency: 7.201 mcs
Message throughput: 138858 msg/s
Server address: 127.0.0.1
Server port: 2222
Working threads: 4
Working clients: 100
Messages to send: 1000000
Message size: 32
Errors: 0
Round-trip time: 4.365 s
Total data: 30.328 MiB
Total messages: 993547
Data throughput: 6.968 MiB/s
Message latency: 4.393 mcs
Message throughput: 227600 msg/s

UDP echo server

Server address: 127.0.0.1
Server port: 3333
Working threads: 1
Working clients: 1
Messages to send: 1000000
Message size: 32
Errors: 0
Round-trip time: 22.071 s
Total data: 30.530 MiB
Total messages: 1000000
Data throughput: 1.391 MiB/s
Message latency: 22.071 mcs
Message throughput: 45306 msg/s
Server address: 127.0.0.1
Server port: 3333
Working threads: 4
Working clients: 100
Messages to send: 1000000
Message size: 32
Errors: 0
Round-trip time: 6.086 s
Total data: 30.512 MiB
Total messages: 999471
Data throughput: 5.011 MiB/s
Message latency: 6.090 mcs
Message throughput: 164201 msg/s

Benchmark: Multicast

Multicast

In this scenario server multicasts messages to all connected clients. The benchmark counts total messages received by all clients for all the working time and measures messages & data throughput, count of errors.

TCP multicast server

Server address: 127.0.0.1
Server port: 1111
Working threads: 1
Working clients: 1
Message size: 32
Errors: 0
Multicast time: 10.002 s
Total data: 970.554 MiB
Total messages: 31802690
Data throughput: 97.027 MiB/s
Message latency: 314 ns
Message throughput: 3179388 msg/s
Server address: 127.0.0.1
Server port: 1111
Working threads: 4
Working clients: 100
Message size: 32
Errors: 0
Multicast time: 10.007 s
Total data: 3.442 GiB
Total messages: 115147638
Data throughput: 351.135 MiB/s
Message latency: 86 ns
Message throughput: 11505891 msg/s

SSL multicast server

Server address: 127.0.0.1
Server port: 2222
Working threads: 1
Working clients: 1
Message size: 32
Errors: 0
Multicast time: 10.011 s
Total data: 458.031 MiB
Total messages: 15008762
Data throughput: 45.769 MiB/s
Message latency: 667 ns
Message throughput: 1499196 msg/s
Server address: 127.0.0.1
Server port: 2222
Working threads: 4
Working clients: 100
Message size: 32
Errors: 0
Multicast time: 10.350 s
Total data: 3.082 GiB
Total messages: 103351505
Data throughput: 304.726 MiB/s
Message latency: 100 ns
Message throughput: 9984724 msg/s

UDP multicast server

Server address: 239.255.0.1
Server port: 3333
Working threads: 1
Working clients: 1
Message size: 32
Errors: 0
Multicast time: 10.004 s
Total data: 19.644 MiB
Total messages: 643205
Data throughput: 1.985 MiB/s
Message latency: 15.553 mcs
Message throughput: 64292 msg/s
Server address: 239.255.0.1
Server port: 3333
Working threads: 4
Working clients: 100
Message size: 32
Errors: 0
Multicast time: 10.007 s
Total data: 78.498 MiB
Total messages: 2571847
Data throughput: 7.862 MiB/s
Message latency: 3.891 mcs
Message throughput: 256982 msg/s

OpenSSL certificates

In order to create OpenSSL based server and client you should prepare a set of SSL certificates. Here comes several steps to get a self-signed set of SSL certificates for testing purposes:

Certificate Authority

  • Create CA private key
openssl genrsa -des3 -passout pass:qwerty -out ca-secret.key 4096
  • Remove passphrase
openssl rsa -passin pass:qwerty -in ca-secret.key -out ca.key
  • Create CA self-signed certificate
openssl req -new -x509 -days 3650 -subj '/C=BY/ST=Belarus/L=Minsk/O=Example root CA/OU=Example CA unit/CN=example.com' -key ca.key -out ca.crt -config openssl.cfg
  • Convert CA self-signed certificate to PKCS
openssl pkcs12 -clcerts -export -passout pass:qwerty -in ca.crt -inkey ca.key -out ca.p12
  • Convert CA self-signed certificate to PEM
openssl pkcs12 -clcerts -passin pass:qwerty -passout pass:qwerty -in ca.p12 -out ca.pem

SSL Server certificate

  • Create private key for the server
openssl genrsa -des3 -passout pass:qwerty -out server-secret.key 4096
  • Remove passphrase
openssl rsa -passin pass:qwerty -in server-secret.key -out server.key
  • Create CSR for the server
openssl req -new -subj '/C=BY/ST=Belarus/L=Minsk/O=Example server/OU=Example server unit/CN=server.example.com' -key server.key -out server.csr -config openssl.cfg
  • Create certificate for the server
openssl x509 -req -days 3650 -in server.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out server.crt
  • Convert the server certificate to PKCS
openssl pkcs12 -clcerts -export -passout pass:qwerty -in server.crt -inkey server.key -out server.p12
  • Convert the server certificate to PEM
openssl pkcs12 -clcerts -passin pass:qwerty -passout pass:qwerty -in server.p12 -out server.pem

SSL Client certificate

  • Create private key for the client
openssl genrsa -des3 -passout pass:qwerty -out client-secret.key 4096
  • Remove passphrase
openssl rsa -passin pass:qwerty -in client-secret.key -out client.key
  • Create CSR for the client
openssl req -new -subj '/C=BY/ST=Belarus/L=Minsk/O=Example client/OU=Example client unit/CN=client.example.com' -key client.key -out client.csr -config openssl.cfg
  • Create the client certificate
openssl x509 -req -days 3650 -in client.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out client.crt
  • Convert the client certificate to PKCS
openssl pkcs12 -clcerts -export -passout pass:qwerty -in client.crt -inkey client.key -out client.p12
  • Convert the client certificate to PEM
openssl pkcs12 -clcerts -passin pass:qwerty -passout pass:qwerty -in client.p12 -out client.pem

Diffie-Hellman key exchange

  • Create DH parameters
openssl dhparam -out dh4096.pem 4096

About

Ultra fast and low latency asynchronous socket server & client C# .NET Core library with support TCP, SSL, UDP protocols and 10K connections problem solution

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

NETCoreServer

Windows build status

Ultra fast and low latency asynchronous socket server & client C# .NET Core library with support TCP, SSL, UDP protocols and 10K connections problem solution.

NETCoreServer documentation
NETCoreServer downloads

Contents

Features

Requirements

How to build?

Setup repository

git clone https://github.com/chronoxor/NETCoreServer.git
cd NETCoreServer

Windows (Visual Studio)

Open and build NETCoreServer.sln or run the build script:

cd build
vs.bat

The build script will create "release" directory with zip files:

  • NETCoreServer.zip - C# Server assembly
  • Benchmarks.zip - C# Server benchmarks
  • Examples.zip - C# Server examples

Examples

Example: Asio timer

Here comes the example of Asio timer. It can be used to wait for some action in future with providing absolute time or relative time span. Asio timer can be used in synchronous or asynchronous modes.

usingSystem;usingSystem.Threading;usingNETCoreServer;namespaceAsioTimer{classAsioTimer:Timer{publicAsioTimer(Serviceservice):base(service){}protectedoverridevoidOnTimer(boolcanceled){Console.WriteLine("Asio timer "+(canceled?"canceled":"expired"));}protectedoverridevoidOnError(interror,stringcategory,stringmessage){Console.WriteLine($"Asio timer caught an error with code {error} and category '{category}': {message}");}}classProgram{staticvoidMain(){// Create a new servicevarservice=newService();// Start the serviceConsole.Write("Service starting...");service.Start();Console.WriteLine("Done!");// Create a new Asio timervartimer=newAsioTimer(service);// Setup and synchronously wait for the timertimer.Setup(DateTime.UtcNow.AddSeconds(1));timer.WaitSync();// Setup and asynchronously wait for the timertimer.Setup(TimeSpan.FromSeconds(1));timer.WaitAsync();// Wait for a while...Thread.Sleep(2000);// Setup and asynchronously wait for the timertimer.Setup(TimeSpan.FromSeconds(1));timer.WaitAsync();// Wait for a while...Thread.Sleep(500);// Cancel the timertimer.Cancel();// Wait for a while...Thread.Sleep(500);// Stop the serviceConsole.Write("Service stopping...");service.Stop();Console.WriteLine("Done!");}}}

Output of the above example is the following:

Service starting...Done!
Asio timer expired
Asio timer canceled
Service stopping...Done!

Example: TCP chat server

Here comes the example of the TCP chat server. It handles multiple TCP client sessions and multicast received message from any session to all ones. Also it is possible to send admin message directly from the server.

usingSystem;usingSystem.Text;usingNETCoreServer;namespaceTcpChatServer{classChatSession:TcpSession{publicChatSession(TcpServerserver):base(server){}protectedoverridevoidOnConnected(){Console.WriteLine($"Chat TCP session with Id {Id} connected!");// Send invite messagestringmessage="Hello from TCP chat! Please send a message or '!' to disconnect the client!";Send(message);}protectedoverridevoidOnDisconnected(){Console.WriteLine($"Chat TCP session with Id {Id} disconnected!");}protectedoverridevoidOnReceived(byte[]buffer){stringmessage=Encoding.UTF8.GetString(buffer);Console.WriteLine("Incoming: "+message);// Multicast message to all connected sessionsServer.Multicast(message);// If the buffer starts with '!' the disconnect the current sessionif(message=="!")Disconnect();}protectedoverridevoidOnError(interror,stringcategory,stringmessage){Console.WriteLine($"Chat TCP session caught an error with code {error} and category '{category}': {message}");}}classChatServer:TcpServer{publicChatServer(Serviceservice,InternetProtocolprotocol,intport):base(service,protocol,port){}protectedoverrideTcpSessionCreateSession(){returnnewChatSession(this);}protectedoverridevoidOnError(interror,stringcategory,stringmessage){Console.WriteLine($"Chat TCP server caught an error with code {error} and category '{category}': {message}");}}classProgram{staticvoidMain(string[]args){// TCP server portintport=1111;if(args.Length>0)port=int.Parse(args[0]);Console.WriteLine($"TCP server port: {port}");// Create a new servicevarservice=newService();// Start the serviceConsole.Write("Service starting...");service.Start();Console.WriteLine("Done!");// Create a new TCP chat servervarserver=newChatServer(service,InternetProtocol.IPv4,port);// Start the serverConsole.Write("Server starting...");server.Start();Console.WriteLine("Done!");Console.WriteLine("Press Enter to stop the server or '!' to restart the server...");// Perform text inputfor(;;){stringline=Console.ReadLine();if(line==String.Empty)break;// Restart the serverif(line=="!"){Console.Write("Server restarting...");server.Restart();Console.WriteLine("Done!");continue;}// Multicast admin message to all sessionsline="(admin) "+line;server.Multicast(line);}// Stop the serverConsole.Write("Server stopping...");server.Stop();Console.WriteLine("Done!");// Stop the serviceConsole.Write("Service stopping...");service.Stop();Console.WriteLine("Done!");}}}

Example: TCP chat client

Here comes the example of the TCP chat client. It connects to the TCP chat server and allows to send message to it and receive new messages.

usingSystem;usingSystem.Text;usingSystem.Threading;usingNETCoreServer;namespaceTcpChatClient{classChatClient:TcpClient{publicChatClient(Serviceservice,stringaddress,intport):base(service,address,port){}publicvoidDisconnectAndStop(){_stop=true;Disconnect();while(IsConnected)Thread.Yield();}protectedoverridevoidOnConnected(){Console.WriteLine($"Chat TCP client connected a new session with Id {Id}");}protectedoverridevoidOnDisconnected(){Console.WriteLine($"Chat TCP client disconnected a session with Id {Id}");// Wait for a while...Thread.Sleep(1000);// Try to connect againif(!_stop)Connect();}protectedoverridevoidOnReceived(byte[]buffer){Console.WriteLine(Encoding.UTF8.GetString(buffer));}protectedoverridevoidOnError(interror,stringcategory,stringmessage){Console.WriteLine($"Chat TCP client caught an error with code {error} and category '{category}': {message}");}privatebool_stop;}classProgram{staticvoidMain(string[]args){// TCP server addressstringaddress="127.0.0.1";if(args.Length>0)address=args[0];// TCP server portintport=1111;if(args.Length>1)port=int.Parse(args[1]);Console.WriteLine($"TCP server address: {address}");Console.WriteLine($"TCP server port: {port}");// Create a new servicevarservice=newService();// Start the serviceConsole.Write("Service starting...");service.Start();Console.WriteLine("Done!");// Create a new TCP chat clientvarclient=newChatClient(service,address,port);// Connect the clientConsole.Write("Client connecting...");client.Connect();Console.WriteLine("Done!");Console.WriteLine("Press Enter to stop the client or '!' to reconnect the client...");// Perform text inputfor(;;){stringline=Console.ReadLine();if(line==String.Empty)break;// Disconnect the clientif(line=="!"){Console.Write("Client disconnecting...");client.Disconnect();Console.WriteLine("Done!");continue;}// Send the entered text to the chat serverclient.Send(line);}// Disconnect the clientConsole.Write("Client disconnecting...");client.DisconnectAndStop();Console.WriteLine("Done!");// Stop the serviceConsole.Write("Service stopping...");service.Stop();Console.WriteLine("Done!");}}}

Example: SSL chat server

Here comes the example of the SSL chat server. It handles multiple SSL client sessions and multicast received message from any session to all ones. Also it is possible to send admin message directly from the server.

This example is very similar to the TCP one except the code that prepares SSL context and handshake handler.

usingSystem;usingSystem.Text;usingNETCoreServer;namespaceSslChatServer{classChatSession:SslSession{publicChatSession(SslServerserver):base(server){}protectedoverridevoidOnConnected(){Console.WriteLine($"Chat SSL session with Id {Id} connected!");// Send invite messagestringmessage="Hello from SSL chat! Please send a message or '!' to disconnect the client!";Send(message);}protectedoverridevoidOnDisconnected(){Console.WriteLine($"Chat SSL session with Id {Id} disconnected!");}protectedoverridevoidOnReceived(byte[]buffer){stringmessage=Encoding.UTF8.GetString(buffer);Console.WriteLine("Incoming: "+message);// Multicast message to all connected sessionsServer.Multicast(message);// If the buffer starts with '!' the disconnect the current sessionif(message=="!")Disconnect();}protectedoverridevoidOnError(interror,stringcategory,stringmessage){Console.WriteLine($"Chat SSL session caught an error with code {error} and category '{category}': {message}");}}classChatServer:SslServer{publicChatServer(Serviceservice,SslContextcontext,InternetProtocolprotocol,intport):base(service,context,protocol,port){}protectedoverrideSslSessionCreateSession(){returnnewChatSession(this);}protectedoverridevoidOnError(interror,stringcategory,stringmessage){Console.WriteLine($"Chat SSL server caught an error with code {error} and category '{category}': {message}");}}classProgram{staticvoidMain(string[]args){// SSL server portintport=2222;if(args.Length>0)port=int.Parse(args[0]);Console.WriteLine($"SSL server port: {port}");// Create a new servicevarservice=newService();// Start the serviceConsole.Write("Service starting...");service.Start();Console.WriteLine("Done!");// Create and prepare a new SSL server contextvarcontext=newSslContext(SslMethod.TLSV12);context.SetPassword("qwerty");context.UseCertificateChainFile("../../../../Tools/certificates/server.pem");context.UsePrivateKeyFile("../../../../Tools/certificates/server.pem",SslFileFormat.PEM);context.UseTmpDHFile("../../../../Tools/certificates/dh4096.pem");// Create a new SSL chat servervarserver=newChatServer(service,context,InternetProtocol.IPv4,port);// Start the serverConsole.Write("Server starting...");server.Start();Console.WriteLine("Done!");Console.WriteLine("Press Enter to stop the server or '!' to restart the server...");// Perform text inputfor(;;){stringline=Console.ReadLine();if(line==String.Empty)break;// Restart the serverif(line=="!"){Console.Write("Server restarting...");server.Restart();Console.WriteLine("Done!");continue;}// Multicast admin message to all sessionsline="(admin) "+line;server.Multicast(line);}// Stop the serverConsole.Write("Server stopping...");server.Stop();Console.WriteLine("Done!");// Stop the serviceConsole.Write("Service stopping...");service.Stop();Console.WriteLine("Done!");}}}

Example: SSL chat client

Here comes the example of the SSL chat client. It connects to the SSL chat server and allows to send message to it and receive new messages.

This example is very similar to the TCP one except the code that prepares SSL context and handshake handler.

usingSystem;usingSystem.Text;usingSystem.Threading;usingNETCoreServer;namespaceSslChatClient{classChatClient:SslClient{publicChatClient(Serviceservice,SslContextcontext,stringaddress,intport):base(service,context,address,port){}publicvoidDisconnectAndStop(){_stop=true;Disconnect();while(IsConnected)Thread.Yield();}protectedoverridevoidOnConnected(){Console.WriteLine($"Chat SSL client connected a new session with Id {Id}");}protectedoverridevoidOnDisconnected(){Console.WriteLine($"Chat SSL client disconnected a session with Id {Id}");// Wait for a while...Thread.Sleep(1000);// Try to connect againif(!_stop)Connect();}protectedoverridevoidOnReceived(byte[]buffer){Console.WriteLine(Encoding.UTF8.GetString(buffer));}protectedoverridevoidOnError(interror,stringcategory,stringmessage){Console.WriteLine($"Chat SSL client caught an error with code {error} and category '{category}': {message}");}privatebool_stop;}classProgram{staticvoidMain(string[]args){// SSL server addressstringaddress="127.0.0.1";if(args.Length>0)address=args[0];// SSL server portintport=2222;if(args.Length>1)port=int.Parse(args[1]);Console.WriteLine($"SSL server address: {address}");Console.WriteLine($"SSL server port: {port}");// Create a new servicevarservice=newService();// Start the serviceConsole.Write("Service starting...");service.Start();Console.WriteLine("Done!");// Create and prepare a new SSL client contextvarcontext=newSslContext(SslMethod.TLSV12);context.SetVerifyMode(SslVerifyMode.VerifyPeer);context.LoadVerifyFile("../../../../Tools/certificates/ca.pem");// Create a new SSL chat clientvarclient=newChatClient(service,context,address,port);// Connect the clientConsole.Write("Client connecting...");client.Connect();Console.WriteLine("Done!");Console.WriteLine("Press Enter to stop the client or '!' to reconnect the client...");// Perform text inputfor(;;){stringline=Console.ReadLine();if(line==String.Empty)break;// Disconnect the clientif(line=="!"){Console.Write("Client disconnecting...");client.Disconnect();Console.WriteLine("Done!");continue;}// Send the entered text to the chat serverclient.Send(line);}// Disconnect the clientConsole.Write("Client disconnecting...");client.DisconnectAndStop();Console.WriteLine("Done!");// Stop the serviceConsole.Write("Service stopping...");service.Stop();Console.WriteLine("Done!");}}}

Example: UDP echo server

Here comes the example of the UDP echo server. It receives a datagram mesage from any UDP client and resend it back without any changes.

usingSystem;usingSystem.Text;usingNETCoreServer;namespaceUdpEchoServer{classEchoServer:UdpServer{publicEchoServer(Serviceservice,InternetProtocolprotocol,intport):base(service,protocol,port){}protectedoverridevoidOnReceived(UdpEndpointendpoint,byte[]buffer){Console.WriteLine("Incoming: "+Encoding.UTF8.GetString(buffer));// Echo the message back to the senderSend(endpoint,buffer);}protectedoverridevoidOnError(interror,stringcategory,stringmessage){Console.WriteLine($"Echo UDP server caught an error with code {error} and category '{category}': {message}");}}classProgram{staticvoidMain(string[]args){// UDP server portintport=3333;if(args.Length>0)port=int.Parse(args[0]);Console.WriteLine($"UDP server port: {port}");// Create a new servicevarservice=newService();// Start the serviceConsole.Write("Service starting...");service.Start();Console.WriteLine("Done!");// Create a new UDP echo servervarserver=newEchoServer(service,InternetProtocol.IPv4,port);// Start the serverConsole.Write("Server starting...");server.Start();Console.WriteLine("Done!");Console.WriteLine("Press Enter to stop the server or '!' to restart the server...");// Perform text inputfor(;;){stringline=Console.ReadLine();if(line==String.Empty)break;// Restart the serverif(line=="!"){Console.Write("Server restarting...");server.Restart();Console.WriteLine("Done!");}}// Stop the serverConsole.Write("Server stopping...");server.Stop();Console.WriteLine("Done!");// Stop the serviceConsole.Write("Service stopping...");service.Stop();Console.WriteLine("Done!");}}}

Example: UDP echo client

Here comes the example of the UDP echo client. It sends user datagram message to UDP server and listen for response.

usingSystem;usingSystem.Text;usingSystem.Threading;usingNETCoreServer;namespaceUdpEchoClient{classEchoClient:UdpClient{publicEchoClient(Serviceservice,stringaddress,intport):base(service,address,port){}publicvoidDisconnectAndStop(){_stop=true;Disconnect();while(IsConnected)Thread.Yield();}protectedoverridevoidOnConnected(){Console.WriteLine($"Echo UDP client connected a new session with Id {Id}");}protectedoverridevoidOnDisconnected(){Console.WriteLine($"Echo UDP client disconnected a session with Id {Id}");// Wait for a while...Thread.Sleep(1000);// Try to connect againif(!_stop)Connect();}protectedoverridevoidOnReceived(UdpEndpointendpoint,byte[]buffer){Console.WriteLine("Incoming: "+Encoding.UTF8.GetString(buffer));}protectedoverridevoidOnError(interror,stringcategory,stringmessage){Console.WriteLine($"Echo UDP client caught an error with code {error} and category '{category}': {message}");}privatebool_stop;}classProgram{staticvoidMain(string[]args){// UDP server addressstringaddress="127.0.0.1";if(args.Length>0)address=args[0];// UDP server portintport=3333;if(args.Length>1)port=int.Parse(args[1]);Console.WriteLine($"UDP server address: {address}");Console.WriteLine($"UDP server port: {port}");// Create a new servicevarservice=newService();// Start the serviceConsole.Write("Service starting...");service.Start();Console.WriteLine("Done!");// Create a new TCP chat clientvarclient=newEchoClient(service,address,port);// Connect the clientConsole.Write("Client connecting...");client.Connect();Console.WriteLine("Done!");Console.WriteLine("Press Enter to stop the client or '!' to reconnect the client...");// Perform text inputfor(;;){stringline=Console.ReadLine();if(line==String.Empty)break;// Disconnect the clientif(line=="!"){Console.Write("Client disconnecting...");client.Disconnect();Console.WriteLine("Done!");continue;}// Send the entered text to the chat serverclient.Send(line);}// Disconnect the clientConsole.Write("Client disconnecting...");client.DisconnectAndStop();Console.WriteLine("Done!");// Stop the serviceConsole.Write("Service stopping...");service.Stop();Console.WriteLine("Done!");}}}

Example: UDP multicast server

Here comes the example of the UDP multicast server. It use multicast IP address to multicast datagram messages to all client that joined corresponding UDP multicast group.

usingSystem;usingSystem.Text;usingNETCoreServer;namespaceUdpMulticastServer{classMulticastServer:UdpServer{publicMulticastServer(Serviceservice,InternetProtocolprotocol,intport):base(service,protocol,port){}protectedoverridevoidOnError(interror,stringcategory,stringmessage){Console.WriteLine($"Multicast UDP server caught an error with code {error} and category '{category}': {message}");}}classProgram{staticvoidMain(string[]args){// UDP multicast addressstringmulticastAddress="239.255.0.1";if(args.Length>0)multicastAddress=args[0];// UDP multicast portintmulticastPort=3334;if(args.Length>1)multicastPort=int.Parse(args[1]);Console.WriteLine($"UDP multicast address: {multicastAddress}");Console.WriteLine($"UDP multicast port: {multicastPort}");// Create a new servicevarservice=newService();// Start the serviceConsole.Write("Service starting...");service.Start();Console.WriteLine("Done!");// Create a new UDP multicast servervarserver=newMulticastServer(service,InternetProtocol.IPv4,0);// Start the multicast serverConsole.Write("Server starting...");server.Start(multicastAddress,multicastPort);Console.WriteLine("Done!");Console.WriteLine("Press Enter to stop the server or '!' to restart the server...");// Perform text inputfor(;;){stringline=Console.ReadLine();if(line==String.Empty)break;// Restart the serverif(line=="!"){Console.Write("Server restarting...");server.Restart();Console.WriteLine("Done!");continue;}// Multicast admin message to all sessionsline="(admin) "+line;server.Multicast(line);}// Stop the serverConsole.Write("Server stopping...");server.Stop();Console.WriteLine("Done!");// Stop the serviceConsole.Write("Service stopping...");service.Stop();Console.WriteLine("Done!");}}}

Example: UDP multicast client

Here comes the example of the UDP multicast client. It use multicast IP address and joins UDP multicast group in order to receive multicasted datagram messages from UDP server.

usingSystem;usingSystem.Text;usingSystem.Threading;usingNETCoreServer;namespaceUdpMulticastClient{classMulticastClient:UdpClient{publicstringMulticast;publicMulticastClient(Serviceservice,stringaddress,intport):base(service,address,port){}publicvoidDisconnectAndStop(){_stop=true;Disconnect();while(IsConnected)Thread.Yield();}protectedoverridevoidOnConnected(){Console.WriteLine($"Multicast UDP client connected a new session with Id {Id}");// Join UDP multicast groupJoinMulticastGroup(Multicast);}protectedoverridevoidOnDisconnected(){Console.WriteLine($"Multicast UDP client disconnected a session with Id {Id}");// Wait for a while...Thread.Sleep(1000);// Try to connect againif(!_stop)Connect();}protectedoverridevoidOnReceived(UdpEndpointendpoint,byte[]buffer){Console.WriteLine("Incoming: "+Encoding.UTF8.GetString(buffer));}protectedoverridevoidOnError(interror,stringcategory,stringmessage){Console.WriteLine($"Multicast UDP client caught an error with code {error} and category '{category}': {message}");}privatebool_stop;}classProgram{staticvoidMain(string[]args){// UDP listen addressstringlistenAddress="0.0.0.0";if(args.Length>0)listenAddress=args[0];// UDP multicast addressstringmulticastAddress="239.255.0.1";if(args.Length>1)multicastAddress=args[1];// UDP multicast portintmulticastPort=3334;if(args.Length>2)multicastPort=int.Parse(args[2]);Console.WriteLine($"UDP listen address: {listenAddress}");Console.WriteLine($"UDP multicast address: {multicastAddress}");Console.WriteLine($"UDP multicast port: {multicastPort}");// Create a new servicevarservice=newService();// Start the serviceConsole.Write("Service starting...");service.Start();Console.WriteLine("Done!");// Create a new TCP chat clientvarclient=newMulticastClient(service,listenAddress,multicastPort);client.SetupMulticast(true);client.Multicast=multicastAddress;// Connect the clientConsole.Write("Client connecting...");client.Connect();Console.WriteLine("Done!");Console.WriteLine("Press Enter to stop the client or '!' to reconnect the client...");// Perform text inputfor(;;){stringline=Console.ReadLine();if(line==String.Empty)break;// Disconnect the clientif(line=="!"){Console.Write("Client disconnecting...");client.Disconnect();Console.WriteLine("Done!");continue;}// Send the entered text to the chat serverclient.Send(line);}// Disconnect the clientConsole.Write("Client disconnecting...");client.DisconnectAndStop();Console.WriteLine("Done!");// Stop the serviceConsole.Write("Service stopping...");service.Stop();Console.WriteLine("Done!");}}}

Performance

Here comes several communication scenarios with timing measurements.

Benchmark environment is the following:

CPU architecutre: Intel(R) Core(TM) i7-4790K CPU @ 4.00GHz
CPU logical cores: 8
CPU physical cores: 4
CPU clock speed: 3.998 GHz
CPU Hyper-Threading: enabled
RAM total: 31.962 GiB
RAM free: 21.623 GiB
OS version: Microsoft Windows 8 Enterprise Edition (build 9200), 64-bit
OS bits: 64-bit
Process bits: 64-bit
Process configuaraion: release

Benchmark: Round-Trip

Round-trip

This scenario sends lots of messages from several clients to a server. The server responses to each message and resend the similar response to the client. The benchmark measures total Round-trip time to send all messages and receive all responses, messages & data throughput, count of errors.

TCP echo server

Server address: 127.0.0.1
Server port: 1111
Working threads: 1
Working clients: 1
Messages to send: 1000000
Message size: 32
Errors: 0
Round-trip time: 3.893 s
Total data: 30.530 MiB
Total messages: 1000000
Data throughput: 7.858 MiB/s
Message latency: 3.893 mcs
Message throughput: 256842 msg/s
Server address: 127.0.0.1
Server port: 1111
Working threads: 4
Working clients: 100
Messages to send: 1000000
Message size: 32
Errors: 0
Round-trip time: 1.557 s
Total data: 30.518 MiB
Total messages: 999632
Data throughput: 19.597 MiB/s
Message latency: 1.558 mcs
Message throughput: 641705 msg/s

SSL echo server

Server address: 127.0.0.1
Server port: 2222
Working threads: 1
Working clients: 1
Messages to send: 1000000
Message size: 32
Errors: 0
Round-trip time: 7.201 s
Total data: 30.530 MiB
Total messages: 1000000
Data throughput: 4.243 MiB/s
Message latency: 7.201 mcs
Message throughput: 138858 msg/s
Server address: 127.0.0.1
Server port: 2222
Working threads: 4
Working clients: 100
Messages to send: 1000000
Message size: 32
Errors: 0
Round-trip time: 4.365 s
Total data: 30.328 MiB
Total messages: 993547
Data throughput: 6.968 MiB/s
Message latency: 4.393 mcs
Message throughput: 227600 msg/s

UDP echo server

Server address: 127.0.0.1
Server port: 3333
Working threads: 1
Working clients: 1
Messages to send: 1000000
Message size: 32
Errors: 0
Round-trip time: 22.071 s
Total data: 30.530 MiB
Total messages: 1000000
Data throughput: 1.391 MiB/s
Message latency: 22.071 mcs
Message throughput: 45306 msg/s
Server address: 127.0.0.1
Server port: 3333
Working threads: 4
Working clients: 100
Messages to send: 1000000
Message size: 32
Errors: 0
Round-trip time: 6.086 s
Total data: 30.512 MiB
Total messages: 999471
Data throughput: 5.011 MiB/s
Message latency: 6.090 mcs
Message throughput: 164201 msg/s

Benchmark: Multicast

Multicast

In this scenario server multicasts messages to all connected clients. The benchmark counts total messages received by all clients for all the working time and measures messages & data throughput, count of errors.

TCP multicast server

Server address: 127.0.0.1
Server port: 1111
Working threads: 1
Working clients: 1
Message size: 32
Errors: 0
Multicast time: 10.002 s
Total data: 970.554 MiB
Total messages: 31802690
Data throughput: 97.027 MiB/s
Message latency: 314 ns
Message throughput: 3179388 msg/s
Server address: 127.0.0.1
Server port: 1111
Working threads: 4
Working clients: 100
Message size: 32
Errors: 0
Multicast time: 10.007 s
Total data: 3.442 GiB
Total messages: 115147638
Data throughput: 351.135 MiB/s
Message latency: 86 ns
Message throughput: 11505891 msg/s

SSL multicast server

Server address: 127.0.0.1
Server port: 2222
Working threads: 1
Working clients: 1
Message size: 32
Errors: 0
Multicast time: 10.011 s
Total data: 458.031 MiB
Total messages: 15008762
Data throughput: 45.769 MiB/s
Message latency: 667 ns
Message throughput: 1499196 msg/s
Server address: 127.0.0.1
Server port: 2222
Working threads: 4
Working clients: 100
Message size: 32
Errors: 0
Multicast time: 10.350 s
Total data: 3.082 GiB
Total messages: 103351505
Data throughput: 304.726 MiB/s
Message latency: 100 ns
Message throughput: 9984724 msg/s

UDP multicast server

Server address: 239.255.0.1
Server port: 3333
Working threads: 1
Working clients: 1
Message size: 32
Errors: 0
Multicast time: 10.004 s
Total data: 19.644 MiB
Total messages: 643205
Data throughput: 1.985 MiB/s
Message latency: 15.553 mcs
Message throughput: 64292 msg/s
Server address: 239.255.0.1
Server port: 3333
Working threads: 4
Working clients: 100
Message size: 32
Errors: 0
Multicast time: 10.007 s
Total data: 78.498 MiB
Total messages: 2571847
Data throughput: 7.862 MiB/s
Message latency: 3.891 mcs
Message throughput: 256982 msg/s

OpenSSL certificates

In order to create OpenSSL based server and client you should prepare a set of SSL certificates. Here comes several steps to get a self-signed set of SSL certificates for testing purposes:

Certificate Authority

  • Create CA private key
openssl genrsa -des3 -passout pass:qwerty -out ca-secret.key 4096
  • Remove passphrase
openssl rsa -passin pass:qwerty -in ca-secret.key -out ca.key
  • Create CA self-signed certificate
openssl req -new -x509 -days 3650 -subj '/C=BY/ST=Belarus/L=Minsk/O=Example root CA/OU=Example CA unit/CN=example.com' -key ca.key -out ca.crt -config openssl.cfg
  • Convert CA self-signed certificate to PKCS
openssl pkcs12 -clcerts -export -passout pass:qwerty -in ca.crt -inkey ca.key -out ca.p12
  • Convert CA self-signed certificate to PEM
openssl pkcs12 -clcerts -passin pass:qwerty -passout pass:qwerty -in ca.p12 -out ca.pem

SSL Server certificate

  • Create private key for the server
openssl genrsa -des3 -passout pass:qwerty -out server-secret.key 4096
  • Remove passphrase
openssl rsa -passin pass:qwerty -in server-secret.key -out server.key
  • Create CSR for the server
openssl req -new -subj '/C=BY/ST=Belarus/L=Minsk/O=Example server/OU=Example server unit/CN=server.example.com' -key server.key -out server.csr -config openssl.cfg
  • Create certificate for the server
openssl x509 -req -days 3650 -in server.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out server.crt
  • Convert the server certificate to PKCS
openssl pkcs12 -clcerts -export -passout pass:qwerty -in server.crt -inkey server.key -out server.p12
  • Convert the server certificate to PEM
openssl pkcs12 -clcerts -passin pass:qwerty -passout pass:qwerty -in server.p12 -out server.pem

SSL Client certificate

  • Create private key for the client
openssl genrsa -des3 -passout pass:qwerty -out client-secret.key 4096
  • Remove passphrase
openssl rsa -passin pass:qwerty -in client-secret.key -out client.key
  • Create CSR for the client
openssl req -new -subj '/C=BY/ST=Belarus/L=Minsk/O=Example client/OU=Example client unit/CN=client.example.com' -key client.key -out client.csr -config openssl.cfg
  • Create the client certificate
openssl x509 -req -days 3650 -in client.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out client.crt
  • Convert the client certificate to PKCS
openssl pkcs12 -clcerts -export -passout pass:qwerty -in client.crt -inkey client.key -out client.p12
  • Convert the client certificate to PEM
openssl pkcs12 -clcerts -passin pass:qwerty -passout pass:qwerty -in client.p12 -out client.pem

Diffie-Hellman key exchange

  • Create DH parameters
openssl dhparam -out dh4096.pem 4096

About

Ultra fast and low latency asynchronous socket server & client C# .NET Core library with support TCP, SSL, UDP protocols and 10K connections problem solution

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

NETCoreServer

Windows build status

Ultra fast and low latency asynchronous socket server & client C# .NET Core library with support TCP, SSL, UDP protocols and 10K connections problem solution.

NETCoreServer documentation
NETCoreServer downloads

Contents

Features

Requirements

How to build?

Setup repository

git clone https://github.com/chronoxor/NETCoreServer.git
cd NETCoreServer

Windows (Visual Studio)

Open and build NETCoreServer.sln or run the build script:

cd build
vs.bat

The build script will create "release" directory with zip files:

  • NETCoreServer.zip - C# Server assembly
  • Benchmarks.zip - C# Server benchmarks
  • Examples.zip - C# Server examples

Examples

Example: Asio timer

Here comes the example of Asio timer. It can be used to wait for some action in future with providing absolute time or relative time span. Asio timer can be used in synchronous or asynchronous modes.

usingSystem;usingSystem.Threading;usingNETCoreServer;namespaceAsioTimer{classAsioTimer:Timer{publicAsioTimer(Serviceservice):base(service){}protectedoverridevoidOnTimer(boolcanceled){Console.WriteLine("Asio timer "+(canceled?"canceled":"expired"));}protectedoverridevoidOnError(interror,stringcategory,stringmessage){Console.WriteLine($"Asio timer caught an error with code {error} and category '{category}': {message}");}}classProgram{staticvoidMain(){// Create a new servicevarservice=newService();// Start the serviceConsole.Write("Service starting...");service.Start();Console.WriteLine("Done!");// Create a new Asio timervartimer=newAsioTimer(service);// Setup and synchronously wait for the timertimer.Setup(DateTime.UtcNow.AddSeconds(1));timer.WaitSync();// Setup and asynchronously wait for the timertimer.Setup(TimeSpan.FromSeconds(1));timer.WaitAsync();// Wait for a while...Thread.Sleep(2000);// Setup and asynchronously wait for the timertimer.Setup(TimeSpan.FromSeconds(1));timer.WaitAsync();// Wait for a while...Thread.Sleep(500);// Cancel the timertimer.Cancel();// Wait for a while...Thread.Sleep(500);// Stop the serviceConsole.Write("Service stopping...");service.Stop();Console.WriteLine("Done!");}}}

Output of the above example is the following:

Service starting...Done!
Asio timer expired
Asio timer canceled
Service stopping...Done!

Example: TCP chat server

Here comes the example of the TCP chat server. It handles multiple TCP client sessions and multicast received message from any session to all ones. Also it is possible to send admin message directly from the server.

usingSystem;usingSystem.Text;usingNETCoreServer;namespaceTcpChatServer{classChatSession:TcpSession{publicChatSession(TcpServerserver):base(server){}protectedoverridevoidOnConnected(){Console.WriteLine($"Chat TCP session with Id {Id} connected!");// Send invite messagestringmessage="Hello from TCP chat! Please send a message or '!' to disconnect the client!";Send(message);}protectedoverridevoidOnDisconnected(){Console.WriteLine($"Chat TCP session with Id {Id} disconnected!");}protectedoverridevoidOnReceived(byte[]buffer){stringmessage=Encoding.UTF8.GetString(buffer);Console.WriteLine("Incoming: "+message);// Multicast message to all connected sessionsServer.Multicast(message);// If the buffer starts with '!' the disconnect the current sessionif(message=="!")Disconnect();}protectedoverridevoidOnError(interror,stringcategory,stringmessage){Console.WriteLine($"Chat TCP session caught an error with code {error} and category '{category}': {message}");}}classChatServer:TcpServer{publicChatServer(Serviceservice,InternetProtocolprotocol,intport):base(service,protocol,port){}protectedoverrideTcpSessionCreateSession(){returnnewChatSession(this);}protectedoverridevoidOnError(interror,stringcategory,stringmessage){Console.WriteLine($"Chat TCP server caught an error with code {error} and category '{category}': {message}");}}classProgram{staticvoidMain(string[]args){// TCP server portintport=1111;if(args.Length>0)port=int.Parse(args[0]);Console.WriteLine($"TCP server port: {port}");// Create a new servicevarservice=newService();// Start the serviceConsole.Write("Service starting...");service.Start();Console.WriteLine("Done!");// Create a new TCP chat servervarserver=newChatServer(service,InternetProtocol.IPv4,port);// Start the serverConsole.Write("Server starting...");server.Start();Console.WriteLine("Done!");Console.WriteLine("Press Enter to stop the server or '!' to restart the server...");// Perform text inputfor(;;){stringline=Console.ReadLine();if(line==String.Empty)break;// Restart the serverif(line=="!"){Console.Write("Server restarting...");server.Restart();Console.WriteLine("Done!");continue;}// Multicast admin message to all sessionsline="(admin) "+line;server.Multicast(line);}// Stop the serverConsole.Write("Server stopping...");server.Stop();Console.WriteLine("Done!");// Stop the serviceConsole.Write("Service stopping...");service.Stop();Console.WriteLine("Done!");}}}

Example: TCP chat client

Here comes the example of the TCP chat client. It connects to the TCP chat server and allows to send message to it and receive new messages.

usingSystem;usingSystem.Text;usingSystem.Threading;usingNETCoreServer;namespaceTcpChatClient{classChatClient:TcpClient{publicChatClient(Serviceservice,stringaddress,intport):base(service,address,port){}publicvoidDisconnectAndStop(){_stop=true;Disconnect();while(IsConnected)Thread.Yield();}protectedoverridevoidOnConnected(){Console.WriteLine($"Chat TCP client connected a new session with Id {Id}");}protectedoverridevoidOnDisconnected(){Console.WriteLine($"Chat TCP client disconnected a session with Id {Id}");// Wait for a while...Thread.Sleep(1000);// Try to connect againif(!_stop)Connect();}protectedoverridevoidOnReceived(byte[]buffer){Console.WriteLine(Encoding.UTF8.GetString(buffer));}protectedoverridevoidOnError(interror,stringcategory,stringmessage){Console.WriteLine($"Chat TCP client caught an error with code {error} and category '{category}': {message}");}privatebool_stop;}classProgram{staticvoidMain(string[]args){// TCP server addressstringaddress="127.0.0.1";if(args.Length>0)address=args[0];// TCP server portintport=1111;if(args.Length>1)port=int.Parse(args[1]);Console.WriteLine($"TCP server address: {address}");Console.WriteLine($"TCP server port: {port}");// Create a new servicevarservice=newService();// Start the serviceConsole.Write("Service starting...");service.Start();Console.WriteLine("Done!");// Create a new TCP chat clientvarclient=newChatClient(service,address,port);// Connect the clientConsole.Write("Client connecting...");client.Connect();Console.WriteLine("Done!");Console.WriteLine("Press Enter to stop the client or '!' to reconnect the client...");// Perform text inputfor(;;){stringline=Console.ReadLine();if(line==String.Empty)break;// Disconnect the clientif(line=="!"){Console.Write("Client disconnecting...");client.Disconnect();Console.WriteLine("Done!");continue;}// Send the entered text to the chat serverclient.Send(line);}// Disconnect the clientConsole.Write("Client disconnecting...");client.DisconnectAndStop();Console.WriteLine("Done!");// Stop the serviceConsole.Write("Service stopping...");service.Stop();Console.WriteLine("Done!");}}}

Example: SSL chat server

Here comes the example of the SSL chat server. It handles multiple SSL client sessions and multicast received message from any session to all ones. Also it is possible to send admin message directly from the server.

This example is very similar to the TCP one except the code that prepares SSL context and handshake handler.

usingSystem;usingSystem.Text;usingNETCoreServer;namespaceSslChatServer{classChatSession:SslSession{publicChatSession(SslServerserver):base(server){}protectedoverridevoidOnConnected(){Console.WriteLine($"Chat SSL session with Id {Id} connected!");// Send invite messagestringmessage="Hello from SSL chat! Please send a message or '!' to disconnect the client!";Send(message);}protectedoverridevoidOnDisconnected(){Console.WriteLine($"Chat SSL session with Id {Id} disconnected!");}protectedoverridevoidOnReceived(byte[]buffer){stringmessage=Encoding.UTF8.GetString(buffer);Console.WriteLine("Incoming: "+message);// Multicast message to all connected sessionsServer.Multicast(message);// If the buffer starts with '!' the disconnect the current sessionif(message=="!")Disconnect();}protectedoverridevoidOnError(interror,stringcategory,stringmessage){Console.WriteLine($"Chat SSL session caught an error with code {error} and category '{category}': {message}");}}classChatServer:SslServer{publicChatServer(Serviceservice,SslContextcontext,InternetProtocolprotocol,intport):base(service,context,protocol,port){}protectedoverrideSslSessionCreateSession(){returnnewChatSession(this);}protectedoverridevoidOnError(interror,stringcategory,stringmessage){Console.WriteLine($"Chat SSL server caught an error with code {error} and category '{category}': {message}");}}classProgram{staticvoidMain(string[]args){// SSL server portintport=2222;if(args.Length>0)port=int.Parse(args[0]);Console.WriteLine($"SSL server port: {port}");// Create a new servicevarservice=newService();// Start the serviceConsole.Write("Service starting...");service.Start();Console.WriteLine("Done!");// Create and prepare a new SSL server contextvarcontext=newSslContext(SslMethod.TLSV12);context.SetPassword("qwerty");context.UseCertificateChainFile("../../../../Tools/certificates/server.pem");context.UsePrivateKeyFile("../../../../Tools/certificates/server.pem",SslFileFormat.PEM);context.UseTmpDHFile("../../../../Tools/certificates/dh4096.pem");// Create a new SSL chat servervarserver=newChatServer(service,context,InternetProtocol.IPv4,port);// Start the serverConsole.Write("Server starting...");server.Start();Console.WriteLine("Done!");Console.WriteLine("Press Enter to stop the server or '!' to restart the server...");// Perform text inputfor(;;){stringline=Console.ReadLine();if(line==String.Empty)break;// Restart the serverif(line=="!"){Console.Write("Server restarting...");server.Restart();Console.WriteLine("Done!");continue;}// Multicast admin message to all sessionsline="(admin) "+line;server.Multicast(line);}// Stop the serverConsole.Write("Server stopping...");server.Stop();Console.WriteLine("Done!");// Stop the serviceConsole.Write("Service stopping...");service.Stop();Console.WriteLine("Done!");}}}

Example: SSL chat client

Here comes the example of the SSL chat client. It connects to the SSL chat server and allows to send message to it and receive new messages.

This example is very similar to the TCP one except the code that prepares SSL context and handshake handler.

usingSystem;usingSystem.Text;usingSystem.Threading;usingNETCoreServer;namespaceSslChatClient{classChatClient:SslClient{publicChatClient(Serviceservice,SslContextcontext,stringaddress,intport):base(service,context,address,port){}publicvoidDisconnectAndStop(){_stop=true;Disconnect();while(IsConnected)Thread.Yield();}protectedoverridevoidOnConnected(){Console.WriteLine($"Chat SSL client connected a new session with Id {Id}");}protectedoverridevoidOnDisconnected(){Console.WriteLine($"Chat SSL client disconnected a session with Id {Id}");// Wait for a while...Thread.Sleep(1000);// Try to connect againif(!_stop)Connect();}protectedoverridevoidOnReceived(byte[]buffer){Console.WriteLine(Encoding.UTF8.GetString(buffer));}protectedoverridevoidOnError(interror,stringcategory,stringmessage){Console.WriteLine($"Chat SSL client caught an error with code {error} and category '{category}': {message}");}privatebool_stop;}classProgram{staticvoidMain(string[]args){// SSL server addressstringaddress="127.0.0.1";if(args.Length>0)address=args[0];// SSL server portintport=2222;if(args.Length>1)port=int.Parse(args[1]);Console.WriteLine($"SSL server address: {address}");Console.WriteLine($"SSL server port: {port}");// Create a new servicevarservice=newService();// Start the serviceConsole.Write("Service starting...");service.Start();Console.WriteLine("Done!");// Create and prepare a new SSL client contextvarcontext=newSslContext(SslMethod.TLSV12);context.SetVerifyMode(SslVerifyMode.VerifyPeer);context.LoadVerifyFile("../../../../Tools/certificates/ca.pem");// Create a new SSL chat clientvarclient=newChatClient(service,context,address,port);// Connect the clientConsole.Write("Client connecting...");client.Connect();Console.WriteLine("Done!");Console.WriteLine("Press Enter to stop the client or '!' to reconnect the client...");// Perform text inputfor(;;){stringline=Console.ReadLine();if(line==String.Empty)break;// Disconnect the clientif(line=="!"){Console.Write("Client disconnecting...");client.Disconnect();Console.WriteLine("Done!");continue;}// Send the entered text to the chat serverclient.Send(line);}// Disconnect the clientConsole.Write("Client disconnecting...");client.DisconnectAndStop();Console.WriteLine("Done!");// Stop the serviceConsole.Write("Service stopping...");service.Stop();Console.WriteLine("Done!");}}}

Example: UDP echo server

Here comes the example of the UDP echo server. It receives a datagram mesage from any UDP client and resend it back without any changes.

usingSystem;usingSystem.Text;usingNETCoreServer;namespaceUdpEchoServer{classEchoServer:UdpServer{publicEchoServer(Serviceservice,InternetProtocolprotocol,intport):base(service,protocol,port){}protectedoverridevoidOnReceived(UdpEndpointendpoint,byte[]buffer){Console.WriteLine("Incoming: "+Encoding.UTF8.GetString(buffer));// Echo the message back to the senderSend(endpoint,buffer);}protectedoverridevoidOnError(interror,stringcategory,stringmessage){Console.WriteLine($"Echo UDP server caught an error with code {error} and category '{category}': {message}");}}classProgram{staticvoidMain(string[]args){// UDP server portintport=3333;if(args.Length>0)port=int.Parse(args[0]);Console.WriteLine($"UDP server port: {port}");// Create a new servicevarservice=newService();// Start the serviceConsole.Write("Service starting...");service.Start();Console.WriteLine("Done!");// Create a new UDP echo servervarserver=newEchoServer(service,InternetProtocol.IPv4,port);// Start the serverConsole.Write("Server starting...");server.Start();Console.WriteLine("Done!");Console.WriteLine("Press Enter to stop the server or '!' to restart the server...");// Perform text inputfor(;;){stringline=Console.ReadLine();if(line==String.Empty)break;// Restart the serverif(line=="!"){Console.Write("Server restarting...");server.Restart();Console.WriteLine("Done!");}}// Stop the serverConsole.Write("Server stopping...");server.Stop();Console.WriteLine("Done!");// Stop the serviceConsole.Write("Service stopping...");service.Stop();Console.WriteLine("Done!");}}}

Example: UDP echo client

Here comes the example of the UDP echo client. It sends user datagram message to UDP server and listen for response.

usingSystem;usingSystem.Text;usingSystem.Threading;usingNETCoreServer;namespaceUdpEchoClient{classEchoClient:UdpClient{publicEchoClient(Serviceservice,stringaddress,intport):base(service,address,port){}publicvoidDisconnectAndStop(){_stop=true;Disconnect();while(IsConnected)Thread.Yield();}protectedoverridevoidOnConnected(){Console.WriteLine($"Echo UDP client connected a new session with Id {Id}");}protectedoverridevoidOnDisconnected(){Console.WriteLine($"Echo UDP client disconnected a session with Id {Id}");// Wait for a while...Thread.Sleep(1000);// Try to connect againif(!_stop)Connect();}protectedoverridevoidOnReceived(UdpEndpointendpoint,byte[]buffer){Console.WriteLine("Incoming: "+Encoding.UTF8.GetString(buffer));}protectedoverridevoidOnError(interror,stringcategory,stringmessage){Console.WriteLine($"Echo UDP client caught an error with code {error} and category '{category}': {message}");}privatebool_stop;}classProgram{staticvoidMain(string[]args){// UDP server addressstringaddress="127.0.0.1";if(args.Length>0)address=args[0];// UDP server portintport=3333;if(args.Length>1)port=int.Parse(args[1]);Console.WriteLine($"UDP server address: {address}");Console.WriteLine($"UDP server port: {port}");// Create a new servicevarservice=newService();// Start the serviceConsole.Write("Service starting...");service.Start();Console.WriteLine("Done!");// Create a new TCP chat clientvarclient=newEchoClient(service,address,port);// Connect the clientConsole.Write("Client connecting...");client.Connect();Console.WriteLine("Done!");Console.WriteLine("Press Enter to stop the client or '!' to reconnect the client...");// Perform text inputfor(;;){stringline=Console.ReadLine();if(line==String.Empty)break;// Disconnect the clientif(line=="!"){Console.Write("Client disconnecting...");client.Disconnect();Console.WriteLine("Done!");continue;}// Send the entered text to the chat serverclient.Send(line);}// Disconnect the clientConsole.Write("Client disconnecting...");client.DisconnectAndStop();Console.WriteLine("Done!");// Stop the serviceConsole.Write("Service stopping...");service.Stop();Console.WriteLine("Done!");}}}

Example: UDP multicast server

Here comes the example of the UDP multicast server. It use multicast IP address to multicast datagram messages to all client that joined corresponding UDP multicast group.

usingSystem;usingSystem.Text;usingNETCoreServer;namespaceUdpMulticastServer{classMulticastServer:UdpServer{publicMulticastServer(Serviceservice,InternetProtocolprotocol,intport):base(service,protocol,port){}protectedoverridevoidOnError(interror,stringcategory,stringmessage){Console.WriteLine($"Multicast UDP server caught an error with code {error} and category '{category}': {message}");}}classProgram{staticvoidMain(string[]args){// UDP multicast addressstringmulticastAddress="239.255.0.1";if(args.Length>0)multicastAddress=args[0];// UDP multicast portintmulticastPort=3334;if(args.Length>1)multicastPort=int.Parse(args[1]);Console.WriteLine($"UDP multicast address: {multicastAddress}");Console.WriteLine($"UDP multicast port: {multicastPort}");// Create a new servicevarservice=newService();// Start the serviceConsole.Write("Service starting...");service.Start();Console.WriteLine("Done!");// Create a new UDP multicast servervarserver=newMulticastServer(service,InternetProtocol.IPv4,0);// Start the multicast serverConsole.Write("Server starting...");server.Start(multicastAddress,multicastPort);Console.WriteLine("Done!");Console.WriteLine("Press Enter to stop the server or '!' to restart the server...");// Perform text inputfor(;;){stringline=Console.ReadLine();if(line==String.Empty)break;// Restart the serverif(line=="!"){Console.Write("Server restarting...");server.Restart();Console.WriteLine("Done!");continue;}// Multicast admin message to all sessionsline="(admin) "+line;server.Multicast(line);}// Stop the serverConsole.Write("Server stopping...");server.Stop();Console.WriteLine("Done!");// Stop the serviceConsole.Write("Service stopping...");service.Stop();Console.WriteLine("Done!");}}}

Example: UDP multicast client

Here comes the example of the UDP multicast client. It use multicast IP address and joins UDP multicast group in order to receive multicasted datagram messages from UDP server.

usingSystem;usingSystem.Text;usingSystem.Threading;usingNETCoreServer;namespaceUdpMulticastClient{classMulticastClient:UdpClient{publicstringMulticast;publicMulticastClient(Serviceservice,stringaddress,intport):base(service,address,port){}publicvoidDisconnectAndStop(){_stop=true;Disconnect();while(IsConnected)Thread.Yield();}protectedoverridevoidOnConnected(){Console.WriteLine($"Multicast UDP client connected a new session with Id {Id}");// Join UDP multicast groupJoinMulticastGroup(Multicast);}protectedoverridevoidOnDisconnected(){Console.WriteLine($"Multicast UDP client disconnected a session with Id {Id}");// Wait for a while...Thread.Sleep(1000);// Try to connect againif(!_stop)Connect();}protectedoverridevoidOnReceived(UdpEndpointendpoint,byte[]buffer){Console.WriteLine("Incoming: "+Encoding.UTF8.GetString(buffer));}protectedoverridevoidOnError(interror,stringcategory,stringmessage){Console.WriteLine($"Multicast UDP client caught an error with code {error} and category '{category}': {message}");}privatebool_stop;}classProgram{staticvoidMain(string[]args){// UDP listen addressstringlistenAddress="0.0.0.0";if(args.Length>0)listenAddress=args[0];// UDP multicast addressstringmulticastAddress="239.255.0.1";if(args.Length>1)multicastAddress=args[1];// UDP multicast portintmulticastPort=3334;if(args.Length>2)multicastPort=int.Parse(args[2]);Console.WriteLine($"UDP listen address: {listenAddress}");Console.WriteLine($"UDP multicast address: {multicastAddress}");Console.WriteLine($"UDP multicast port: {multicastPort}");// Create a new servicevarservice=newService();// Start the serviceConsole.Write("Service starting...");service.Start();Console.WriteLine("Done!");// Create a new TCP chat clientvarclient=newMulticastClient(service,listenAddress,multicastPort);client.SetupMulticast(true);client.Multicast=multicastAddress;// Connect the clientConsole.Write("Client connecting...");client.Connect();Console.WriteLine("Done!");Console.WriteLine("Press Enter to stop the client or '!' to reconnect the client...");// Perform text inputfor(;;){stringline=Console.ReadLine();if(line==String.Empty)break;// Disconnect the clientif(line=="!"){Console.Write("Client disconnecting...");client.Disconnect();Console.WriteLine("Done!");continue;}// Send the entered text to the chat serverclient.Send(line);}// Disconnect the clientConsole.Write("Client disconnecting...");client.DisconnectAndStop();Console.WriteLine("Done!");// Stop the serviceConsole.Write("Service stopping...");service.Stop();Console.WriteLine("Done!");}}}

Performance

Here comes several communication scenarios with timing measurements.

Benchmark environment is the following:

CPU architecutre: Intel(R) Core(TM) i7-4790K CPU @ 4.00GHz
CPU logical cores: 8
CPU physical cores: 4
CPU clock speed: 3.998 GHz
CPU Hyper-Threading: enabled
RAM total: 31.962 GiB
RAM free: 21.623 GiB
OS version: Microsoft Windows 8 Enterprise Edition (build 9200), 64-bit
OS bits: 64-bit
Process bits: 64-bit
Process configuaraion: release

Benchmark: Round-Trip

Round-trip

This scenario sends lots of messages from several clients to a server. The server responses to each message and resend the similar response to the client. The benchmark measures total Round-trip time to send all messages and receive all responses, messages & data throughput, count of errors.

TCP echo server

Server address: 127.0.0.1
Server port: 1111
Working threads: 1
Working clients: 1
Messages to send: 1000000
Message size: 32
Errors: 0
Round-trip time: 3.893 s
Total data: 30.530 MiB
Total messages: 1000000
Data throughput: 7.858 MiB/s
Message latency: 3.893 mcs
Message throughput: 256842 msg/s
Server address: 127.0.0.1
Server port: 1111
Working threads: 4
Working clients: 100
Messages to send: 1000000
Message size: 32
Errors: 0
Round-trip time: 1.557 s
Total data: 30.518 MiB
Total messages: 999632
Data throughput: 19.597 MiB/s
Message latency: 1.558 mcs
Message throughput: 641705 msg/s

SSL echo server

Server address: 127.0.0.1
Server port: 2222
Working threads: 1
Working clients: 1
Messages to send: 1000000
Message size: 32
Errors: 0
Round-trip time: 7.201 s
Total data: 30.530 MiB
Total messages: 1000000
Data throughput: 4.243 MiB/s
Message latency: 7.201 mcs
Message throughput: 138858 msg/s
Server address: 127.0.0.1
Server port: 2222
Working threads: 4
Working clients: 100
Messages to send: 1000000
Message size: 32
Errors: 0
Round-trip time: 4.365 s
Total data: 30.328 MiB
Total messages: 993547
Data throughput: 6.968 MiB/s
Message latency: 4.393 mcs
Message throughput: 227600 msg/s

UDP echo server

Server address: 127.0.0.1
Server port: 3333
Working threads: 1
Working clients: 1
Messages to send: 1000000
Message size: 32
Errors: 0
Round-trip time: 22.071 s
Total data: 30.530 MiB
Total messages: 1000000
Data throughput: 1.391 MiB/s
Message latency: 22.071 mcs
Message throughput: 45306 msg/s
Server address: 127.0.0.1
Server port: 3333
Working threads: 4
Working clients: 100
Messages to send: 1000000
Message size: 32
Errors: 0
Round-trip time: 6.086 s
Total data: 30.512 MiB
Total messages: 999471
Data throughput: 5.011 MiB/s
Message latency: 6.090 mcs
Message throughput: 164201 msg/s

Benchmark: Multicast

Multicast

In this scenario server multicasts messages to all connected clients. The benchmark counts total messages received by all clients for all the working time and measures messages & data throughput, count of errors.

TCP multicast server

Server address: 127.0.0.1
Server port: 1111
Working threads: 1
Working clients: 1
Message size: 32
Errors: 0
Multicast time: 10.002 s
Total data: 970.554 MiB
Total messages: 31802690
Data throughput: 97.027 MiB/s
Message latency: 314 ns
Message throughput: 3179388 msg/s
Server address: 127.0.0.1
Server port: 1111
Working threads: 4
Working clients: 100
Message size: 32
Errors: 0
Multicast time: 10.007 s
Total data: 3.442 GiB
Total messages: 115147638
Data throughput: 351.135 MiB/s
Message latency: 86 ns
Message throughput: 11505891 msg/s

SSL multicast server

Server address: 127.0.0.1
Server port: 2222
Working threads: 1
Working clients: 1
Message size: 32
Errors: 0
Multicast time: 10.011 s
Total data: 458.031 MiB
Total messages: 15008762
Data throughput: 45.769 MiB/s
Message latency: 667 ns
Message throughput: 1499196 msg/s
Server address: 127.0.0.1
Server port: 2222
Working threads: 4
Working clients: 100
Message size: 32
Errors: 0
Multicast time: 10.350 s
Total data: 3.082 GiB
Total messages: 103351505
Data throughput: 304.726 MiB/s
Message latency: 100 ns
Message throughput: 9984724 msg/s

UDP multicast server

Server address: 239.255.0.1
Server port: 3333
Working threads: 1
Working clients: 1
Message size: 32
Errors: 0
Multicast time: 10.004 s
Total data: 19.644 MiB
Total messages: 643205
Data throughput: 1.985 MiB/s
Message latency: 15.553 mcs
Message throughput: 64292 msg/s
Server address: 239.255.0.1
Server port: 3333
Working threads: 4
Working clients: 100
Message size: 32
Errors: 0
Multicast time: 10.007 s
Total data: 78.498 MiB
Total messages: 2571847
Data throughput: 7.862 MiB/s
Message latency: 3.891 mcs
Message throughput: 256982 msg/s

OpenSSL certificates

In order to create OpenSSL based server and client you should prepare a set of SSL certificates. Here comes several steps to get a self-signed set of SSL certificates for testing purposes:

Certificate Authority

  • Create CA private key
openssl genrsa -des3 -passout pass:qwerty -out ca-secret.key 4096
  • Remove passphrase
openssl rsa -passin pass:qwerty -in ca-secret.key -out ca.key
  • Create CA self-signed certificate
openssl req -new -x509 -days 3650 -subj '/C=BY/ST=Belarus/L=Minsk/O=Example root CA/OU=Example CA unit/CN=example.com' -key ca.key -out ca.crt -config openssl.cfg
  • Convert CA self-signed certificate to PKCS
openssl pkcs12 -clcerts -export -passout pass:qwerty -in ca.crt -inkey ca.key -out ca.p12
  • Convert CA self-signed certificate to PEM
openssl pkcs12 -clcerts -passin pass:qwerty -passout pass:qwerty -in ca.p12 -out ca.pem

SSL Server certificate

  • Create private key for the server
openssl genrsa -des3 -passout pass:qwerty -out server-secret.key 4096
  • Remove passphrase
openssl rsa -passin pass:qwerty -in server-secret.key -out server.key
  • Create CSR for the server
openssl req -new -subj '/C=BY/ST=Belarus/L=Minsk/O=Example server/OU=Example server unit/CN=server.example.com' -key server.key -out server.csr -config openssl.cfg
  • Create certificate for the server
openssl x509 -req -days 3650 -in server.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out server.crt
  • Convert the server certificate to PKCS
openssl pkcs12 -clcerts -export -passout pass:qwerty -in server.crt -inkey server.key -out server.p12
  • Convert the server certificate to PEM
openssl pkcs12 -clcerts -passin pass:qwerty -passout pass:qwerty -in server.p12 -out server.pem

SSL Client certificate

  • Create private key for the client
openssl genrsa -des3 -passout pass:qwerty -out client-secret.key 4096
  • Remove passphrase
openssl rsa -passin pass:qwerty -in client-secret.key -out client.key
  • Create CSR for the client
openssl req -new -subj '/C=BY/ST=Belarus/L=Minsk/O=Example client/OU=Example client unit/CN=client.example.com' -key client.key -out client.csr -config openssl.cfg
  • Create the client certificate
openssl x509 -req -days 3650 -in client.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out client.crt
  • Convert the client certificate to PKCS
openssl pkcs12 -clcerts -export -passout pass:qwerty -in client.crt -inkey client.key -out client.p12
  • Convert the client certificate to PEM
openssl pkcs12 -clcerts -passin pass:qwerty -passout pass:qwerty -in client.p12 -out client.pem

Diffie-Hellman key exchange

  • Create DH parameters
openssl dhparam -out dh4096.pem 4096

About

Ultra fast and low latency asynchronous socket server & client C# .NET Core library with support TCP, SSL, UDP protocols and 10K connections problem solution

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

NETCoreServer

Windows build status

Ultra fast and low latency asynchronous socket server & client C# .NET Core library with support TCP, SSL, UDP protocols and 10K connections problem solution.

NETCoreServer documentation
NETCoreServer downloads

Contents

Features

Requirements

How to build?

Setup repository

git clone https://github.com/chronoxor/NETCoreServer.git
cd NETCoreServer

Windows (Visual Studio)

Open and build NETCoreServer.sln or run the build script:

cd build
vs.bat

The build script will create "release" directory with zip files:

  • NETCoreServer.zip - C# Server assembly
  • Benchmarks.zip - C# Server benchmarks
  • Examples.zip - C# Server examples

Examples

Example: Asio timer

Here comes the example of Asio timer. It can be used to wait for some action in future with providing absolute time or relative time span. Asio timer can be used in synchronous or asynchronous modes.

usingSystem;usingSystem.Threading;usingNETCoreServer;namespaceAsioTimer{classAsioTimer:Timer{publicAsioTimer(Serviceservice):base(service){}protectedoverridevoidOnTimer(boolcanceled){Console.WriteLine("Asio timer "+(canceled?"canceled":"expired"));}protectedoverridevoidOnError(interror,stringcategory,stringmessage){Console.WriteLine($"Asio timer caught an error with code {error} and category '{category}': {message}");}}classProgram{staticvoidMain(){// Create a new servicevarservice=newService();// Start the serviceConsole.Write("Service starting...");service.Start();Console.WriteLine("Done!");// Create a new Asio timervartimer=newAsioTimer(service);// Setup and synchronously wait for the timertimer.Setup(DateTime.UtcNow.AddSeconds(1));timer.WaitSync();// Setup and asynchronously wait for the timertimer.Setup(TimeSpan.FromSeconds(1));timer.WaitAsync();// Wait for a while...Thread.Sleep(2000);// Setup and asynchronously wait for the timertimer.Setup(TimeSpan.FromSeconds(1));timer.WaitAsync();// Wait for a while...Thread.Sleep(500);// Cancel the timertimer.Cancel();// Wait for a while...Thread.Sleep(500);// Stop the serviceConsole.Write("Service stopping...");service.Stop();Console.WriteLine("Done!");}}}

Output of the above example is the following:

Service starting...Done!
Asio timer expired
Asio timer canceled
Service stopping...Done!

Example: TCP chat server

Here comes the example of the TCP chat server. It handles multiple TCP client sessions and multicast received message from any session to all ones. Also it is possible to send admin message directly from the server.

usingSystem;usingSystem.Text;usingNETCoreServer;namespaceTcpChatServer{classChatSession:TcpSession{publicChatSession(TcpServerserver):base(server){}protectedoverridevoidOnConnected(){Console.WriteLine($"Chat TCP session with Id {Id} connected!");// Send invite messagestringmessage="Hello from TCP chat! Please send a message or '!' to disconnect the client!";Send(message);}protectedoverridevoidOnDisconnected(){Console.WriteLine($"Chat TCP session with Id {Id} disconnected!");}protectedoverridevoidOnReceived(byte[]buffer){stringmessage=Encoding.UTF8.GetString(buffer);Console.WriteLine("Incoming: "+message);// Multicast message to all connected sessionsServer.Multicast(message);// If the buffer starts with '!' the disconnect the current sessionif(message=="!")Disconnect();}protectedoverridevoidOnError(interror,stringcategory,stringmessage){Console.WriteLine($"Chat TCP session caught an error with code {error} and category '{category}': {message}");}}classChatServer:TcpServer{publicChatServer(Serviceservice,InternetProtocolprotocol,intport):base(service,protocol,port){}protectedoverrideTcpSessionCreateSession(){returnnewChatSession(this);}protectedoverridevoidOnError(interror,stringcategory,stringmessage){Console.WriteLine($"Chat TCP server caught an error with code {error} and category '{category}': {message}");}}classProgram{staticvoidMain(string[]args){// TCP server portintport=1111;if(args.Length>0)port=int.Parse(args[0]);Console.WriteLine($"TCP server port: {port}");// Create a new servicevarservice=newService();// Start the serviceConsole.Write("Service starting...");service.Start();Console.WriteLine("Done!");// Create a new TCP chat servervarserver=newChatServer(service,InternetProtocol.IPv4,port);// Start the serverConsole.Write("Server starting...");server.Start();Console.WriteLine("Done!");Console.WriteLine("Press Enter to stop the server or '!' to restart the server...");// Perform text inputfor(;;){stringline=Console.ReadLine();if(line==String.Empty)break;// Restart the serverif(line=="!"){Console.Write("Server restarting...");server.Restart();Console.WriteLine("Done!");continue;}// Multicast admin message to all sessionsline="(admin) "+line;server.Multicast(line);}// Stop the serverConsole.Write("Server stopping...");server.Stop();Console.WriteLine("Done!");// Stop the serviceConsole.Write("Service stopping...");service.Stop();Console.WriteLine("Done!");}}}

Example: TCP chat client

Here comes the example of the TCP chat client. It connects to the TCP chat server and allows to send message to it and receive new messages.

usingSystem;usingSystem.Text;usingSystem.Threading;usingNETCoreServer;namespaceTcpChatClient{classChatClient:TcpClient{publicChatClient(Serviceservice,stringaddress,intport):base(service,address,port){}publicvoidDisconnectAndStop(){_stop=true;Disconnect();while(IsConnected)Thread.Yield();}protectedoverridevoidOnConnected(){Console.WriteLine($"Chat TCP client connected a new session with Id {Id}");}protectedoverridevoidOnDisconnected(){Console.WriteLine($"Chat TCP client disconnected a session with Id {Id}");// Wait for a while...Thread.Sleep(1000);// Try to connect againif(!_stop)Connect();}protectedoverridevoidOnReceived(byte[]buffer){Console.WriteLine(Encoding.UTF8.GetString(buffer));}protectedoverridevoidOnError(interror,stringcategory,stringmessage){Console.WriteLine($"Chat TCP client caught an error with code {error} and category '{category}': {message}");}privatebool_stop;}classProgram{staticvoidMain(string[]args){// TCP server addressstringaddress="127.0.0.1";if(args.Length>0)address=args[0];// TCP server portintport=1111;if(args.Length>1)port=int.Parse(args[1]);Console.WriteLine($"TCP server address: {address}");Console.WriteLine($"TCP server port: {port}");// Create a new servicevarservice=newService();// Start the serviceConsole.Write("Service starting...");service.Start();Console.WriteLine("Done!");// Create a new TCP chat clientvarclient=newChatClient(service,address,port);// Connect the clientConsole.Write("Client connecting...");client.Connect();Console.WriteLine("Done!");Console.WriteLine("Press Enter to stop the client or '!' to reconnect the client...");// Perform text inputfor(;;){stringline=Console.ReadLine();if(line==String.Empty)break;// Disconnect the clientif(line=="!"){Console.Write("Client disconnecting...");client.Disconnect();Console.WriteLine("Done!");continue;}// Send the entered text to the chat serverclient.Send(line);}// Disconnect the clientConsole.Write("Client disconnecting...");client.DisconnectAndStop();Console.WriteLine("Done!");// Stop the serviceConsole.Write("Service stopping...");service.Stop();Console.WriteLine("Done!");}}}

Example: SSL chat server

Here comes the example of the SSL chat server. It handles multiple SSL client sessions and multicast received message from any session to all ones. Also it is possible to send admin message directly from the server.

This example is very similar to the TCP one except the code that prepares SSL context and handshake handler.

usingSystem;usingSystem.Text;usingNETCoreServer;namespaceSslChatServer{classChatSession:SslSession{publicChatSession(SslServerserver):base(server){}protectedoverridevoidOnConnected(){Console.WriteLine($"Chat SSL session with Id {Id} connected!");// Send invite messagestringmessage="Hello from SSL chat! Please send a message or '!' to disconnect the client!";Send(message);}protectedoverridevoidOnDisconnected(){Console.WriteLine($"Chat SSL session with Id {Id} disconnected!");}protectedoverridevoidOnReceived(byte[]buffer){stringmessage=Encoding.UTF8.GetString(buffer);Console.WriteLine("Incoming: "+message);// Multicast message to all connected sessionsServer.Multicast(message);// If the buffer starts with '!' the disconnect the current sessionif(message=="!")Disconnect();}protectedoverridevoidOnError(interror,stringcategory,stringmessage){Console.WriteLine($"Chat SSL session caught an error with code {error} and category '{category}': {message}");}}classChatServer:SslServer{publicChatServer(Serviceservice,SslContextcontext,InternetProtocolprotocol,intport):base(service,context,protocol,port){}protectedoverrideSslSessionCreateSession(){returnnewChatSession(this);}protectedoverridevoidOnError(interror,stringcategory,stringmessage){Console.WriteLine($"Chat SSL server caught an error with code {error} and category '{category}': {message}");}}classProgram{staticvoidMain(string[]args){// SSL server portintport=2222;if(args.Length>0)port=int.Parse(args[0]);Console.WriteLine($"SSL server port: {port}");// Create a new servicevarservice=newService();// Start the serviceConsole.Write("Service starting...");service.Start();Console.WriteLine("Done!");// Create and prepare a new SSL server contextvarcontext=newSslContext(SslMethod.TLSV12);context.SetPassword("qwerty");context.UseCertificateChainFile("../../../../Tools/certificates/server.pem");context.UsePrivateKeyFile("../../../../Tools/certificates/server.pem",SslFileFormat.PEM);context.UseTmpDHFile("../../../../Tools/certificates/dh4096.pem");// Create a new SSL chat servervarserver=newChatServer(service,context,InternetProtocol.IPv4,port);// Start the serverConsole.Write("Server starting...");server.Start();Console.WriteLine("Done!");Console.WriteLine("Press Enter to stop the server or '!' to restart the server...");// Perform text inputfor(;;){stringline=Console.ReadLine();if(line==String.Empty)break;// Restart the serverif(line=="!"){Console.Write("Server restarting...");server.Restart();Console.WriteLine("Done!");continue;}// Multicast admin message to all sessionsline="(admin) "+line;server.Multicast(line);}// Stop the serverConsole.Write("Server stopping...");server.Stop();Console.WriteLine("Done!");// Stop the serviceConsole.Write("Service stopping...");service.Stop();Console.WriteLine("Done!");}}}

Example: SSL chat client

Here comes the example of the SSL chat client. It connects to the SSL chat server and allows to send message to it and receive new messages.

This example is very similar to the TCP one except the code that prepares SSL context and handshake handler.

usingSystem;usingSystem.Text;usingSystem.Threading;usingNETCoreServer;namespaceSslChatClient{classChatClient:SslClient{publicChatClient(Serviceservice,SslContextcontext,stringaddress,intport):base(service,context,address,port){}publicvoidDisconnectAndStop(){_stop=true;Disconnect();while(IsConnected)Thread.Yield();}protectedoverridevoidOnConnected(){Console.WriteLine($"Chat SSL client connected a new session with Id {Id}");}protectedoverridevoidOnDisconnected(){Console.WriteLine($"Chat SSL client disconnected a session with Id {Id}");// Wait for a while...Thread.Sleep(1000);// Try to connect againif(!_stop)Connect();}protectedoverridevoidOnReceived(byte[]buffer){Console.WriteLine(Encoding.UTF8.GetString(buffer));}protectedoverridevoidOnError(interror,stringcategory,stringmessage){Console.WriteLine($"Chat SSL client caught an error with code {error} and category '{category}': {message}");}privatebool_stop;}classProgram{staticvoidMain(string[]args){// SSL server addressstringaddress="127.0.0.1";if(args.Length>0)address=args[0];// SSL server portintport=2222;if(args.Length>1)port=int.Parse(args[1]);Console.WriteLine($"SSL server address: {address}");Console.WriteLine($"SSL server port: {port}");// Create a new servicevarservice=newService();// Start the serviceConsole.Write("Service starting...");service.Start();Console.WriteLine("Done!");// Create and prepare a new SSL client contextvarcontext=newSslContext(SslMethod.TLSV12);context.SetVerifyMode(SslVerifyMode.VerifyPeer);context.LoadVerifyFile("../../../../Tools/certificates/ca.pem");// Create a new SSL chat clientvarclient=newChatClient(service,context,address,port);// Connect the clientConsole.Write("Client connecting...");client.Connect();Console.WriteLine("Done!");Console.WriteLine("Press Enter to stop the client or '!' to reconnect the client...");// Perform text inputfor(;;){stringline=Console.ReadLine();if(line==String.Empty)break;// Disconnect the clientif(line=="!"){Console.Write("Client disconnecting...");client.Disconnect();Console.WriteLine("Done!");continue;}// Send the entered text to the chat serverclient.Send(line);}// Disconnect the clientConsole.Write("Client disconnecting...");client.DisconnectAndStop();Console.WriteLine("Done!");// Stop the serviceConsole.Write("Service stopping...");service.Stop();Console.WriteLine("Done!");}}}

Example: UDP echo server

Here comes the example of the UDP echo server. It receives a datagram mesage from any UDP client and resend it back without any changes.

usingSystem;usingSystem.Text;usingNETCoreServer;namespaceUdpEchoServer{classEchoServer:UdpServer{publicEchoServer(Serviceservice,InternetProtocolprotocol,intport):base(service,protocol,port){}protectedoverridevoidOnReceived(UdpEndpointendpoint,byte[]buffer){Console.WriteLine("Incoming: "+Encoding.UTF8.GetString(buffer));// Echo the message back to the senderSend(endpoint,buffer);}protectedoverridevoidOnError(interror,stringcategory,stringmessage){Console.WriteLine($"Echo UDP server caught an error with code {error} and category '{category}': {message}");}}classProgram{staticvoidMain(string[]args){// UDP server portintport=3333;if(args.Length>0)port=int.Parse(args[0]);Console.WriteLine($"UDP server port: {port}");// Create a new servicevarservice=newService();// Start the serviceConsole.Write("Service starting...");service.Start();Console.WriteLine("Done!");// Create a new UDP echo servervarserver=newEchoServer(service,InternetProtocol.IPv4,port);// Start the serverConsole.Write("Server starting...");server.Start();Console.WriteLine("Done!");Console.WriteLine("Press Enter to stop the server or '!' to restart the server...");// Perform text inputfor(;;){stringline=Console.ReadLine();if(line==String.Empty)break;// Restart the serverif(line=="!"){Console.Write("Server restarting...");server.Restart();Console.WriteLine("Done!");}}// Stop the serverConsole.Write("Server stopping...");server.Stop();Console.WriteLine("Done!");// Stop the serviceConsole.Write("Service stopping...");service.Stop();Console.WriteLine("Done!");}}}

Example: UDP echo client

Here comes the example of the UDP echo client. It sends user datagram message to UDP server and listen for response.

usingSystem;usingSystem.Text;usingSystem.Threading;usingNETCoreServer;namespaceUdpEchoClient{classEchoClient:UdpClient{publicEchoClient(Serviceservice,stringaddress,intport):base(service,address,port){}publicvoidDisconnectAndStop(){_stop=true;Disconnect();while(IsConnected)Thread.Yield();}protectedoverridevoidOnConnected(){Console.WriteLine($"Echo UDP client connected a new session with Id {Id}");}protectedoverridevoidOnDisconnected(){Console.WriteLine($"Echo UDP client disconnected a session with Id {Id}");// Wait for a while...Thread.Sleep(1000);// Try to connect againif(!_stop)Connect();}protectedoverridevoidOnReceived(UdpEndpointendpoint,byte[]buffer){Console.WriteLine("Incoming: "+Encoding.UTF8.GetString(buffer));}protectedoverridevoidOnError(interror,stringcategory,stringmessage){Console.WriteLine($"Echo UDP client caught an error with code {error} and category '{category}': {message}");}privatebool_stop;}classProgram{staticvoidMain(string[]args){// UDP server addressstringaddress="127.0.0.1";if(args.Length>0)address=args[0];// UDP server portintport=3333;if(args.Length>1)port=int.Parse(args[1]);Console.WriteLine($"UDP server address: {address}");Console.WriteLine($"UDP server port: {port}");// Create a new servicevarservice=newService();// Start the serviceConsole.Write("Service starting...");service.Start();Console.WriteLine("Done!");// Create a new TCP chat clientvarclient=newEchoClient(service,address,port);// Connect the clientConsole.Write("Client connecting...");client.Connect();Console.WriteLine("Done!");Console.WriteLine("Press Enter to stop the client or '!' to reconnect the client...");// Perform text inputfor(;;){stringline=Console.ReadLine();if(line==String.Empty)break;// Disconnect the clientif(line=="!"){Console.Write("Client disconnecting...");client.Disconnect();Console.WriteLine("Done!");continue;}// Send the entered text to the chat serverclient.Send(line);}// Disconnect the clientConsole.Write("Client disconnecting...");client.DisconnectAndStop();Console.WriteLine("Done!");// Stop the serviceConsole.Write("Service stopping...");service.Stop();Console.WriteLine("Done!");}}}

Example: UDP multicast server

Here comes the example of the UDP multicast server. It use multicast IP address to multicast datagram messages to all client that joined corresponding UDP multicast group.

usingSystem;usingSystem.Text;usingNETCoreServer;namespaceUdpMulticastServer{classMulticastServer:UdpServer{publicMulticastServer(Serviceservice,InternetProtocolprotocol,intport):base(service,protocol,port){}protectedoverridevoidOnError(interror,stringcategory,stringmessage){Console.WriteLine($"Multicast UDP server caught an error with code {error} and category '{category}': {message}");}}classProgram{staticvoidMain(string[]args){// UDP multicast addressstringmulticastAddress="239.255.0.1";if(args.Length>0)multicastAddress=args[0];// UDP multicast portintmulticastPort=3334;if(args.Length>1)multicastPort=int.Parse(args[1]);Console.WriteLine($"UDP multicast address: {multicastAddress}");Console.WriteLine($"UDP multicast port: {multicastPort}");// Create a new servicevarservice=newService();// Start the serviceConsole.Write("Service starting...");service.Start();Console.WriteLine("Done!");// Create a new UDP multicast servervarserver=newMulticastServer(service,InternetProtocol.IPv4,0);// Start the multicast serverConsole.Write("Server starting...");server.Start(multicastAddress,multicastPort);Console.WriteLine("Done!");Console.WriteLine("Press Enter to stop the server or '!' to restart the server...");// Perform text inputfor(;;){stringline=Console.ReadLine();if(line==String.Empty)break;// Restart the serverif(line=="!"){Console.Write("Server restarting...");server.Restart();Console.WriteLine("Done!");continue;}// Multicast admin message to all sessionsline="(admin) "+line;server.Multicast(line);}// Stop the serverConsole.Write("Server stopping...");server.Stop();Console.WriteLine("Done!");// Stop the serviceConsole.Write("Service stopping...");service.Stop();Console.WriteLine("Done!");}}}

Example: UDP multicast client

Here comes the example of the UDP multicast client. It use multicast IP address and joins UDP multicast group in order to receive multicasted datagram messages from UDP server.

usingSystem;usingSystem.Text;usingSystem.Threading;usingNETCoreServer;namespaceUdpMulticastClient{classMulticastClient:UdpClient{publicstringMulticast;publicMulticastClient(Serviceservice,stringaddress,intport):base(service,address,port){}publicvoidDisconnectAndStop(){_stop=true;Disconnect();while(IsConnected)Thread.Yield();}protectedoverridevoidOnConnected(){Console.WriteLine($"Multicast UDP client connected a new session with Id {Id}");// Join UDP multicast groupJoinMulticastGroup(Multicast);}protectedoverridevoidOnDisconnected(){Console.WriteLine($"Multicast UDP client disconnected a session with Id {Id}");// Wait for a while...Thread.Sleep(1000);// Try to connect againif(!_stop)Connect();}protectedoverridevoidOnReceived(UdpEndpointendpoint,byte[]buffer){Console.WriteLine("Incoming: "+Encoding.UTF8.GetString(buffer));}protectedoverridevoidOnError(interror,stringcategory,stringmessage){Console.WriteLine($"Multicast UDP client caught an error with code {error} and category '{category}': {message}");}privatebool_stop;}classProgram{staticvoidMain(string[]args){// UDP listen addressstringlistenAddress="0.0.0.0";if(args.Length>0)listenAddress=args[0];// UDP multicast addressstringmulticastAddress="239.255.0.1";if(args.Length>1)multicastAddress=args[1];// UDP multicast portintmulticastPort=3334;if(args.Length>2)multicastPort=int.Parse(args[2]);Console.WriteLine($"UDP listen address: {listenAddress}");Console.WriteLine($"UDP multicast address: {multicastAddress}");Console.WriteLine($"UDP multicast port: {multicastPort}");// Create a new servicevarservice=newService();// Start the serviceConsole.Write("Service starting...");service.Start();Console.WriteLine("Done!");// Create a new TCP chat clientvarclient=newMulticastClient(service,listenAddress,multicastPort);client.SetupMulticast(true);client.Multicast=multicastAddress;// Connect the clientConsole.Write("Client connecting...");client.Connect();Console.WriteLine("Done!");Console.WriteLine("Press Enter to stop the client or '!' to reconnect the client...");// Perform text inputfor(;;){stringline=Console.ReadLine();if(line==String.Empty)break;// Disconnect the clientif(line=="!"){Console.Write("Client disconnecting...");client.Disconnect();Console.WriteLine("Done!");continue;}// Send the entered text to the chat serverclient.Send(line);}// Disconnect the clientConsole.Write("Client disconnecting...");client.DisconnectAndStop();Console.WriteLine("Done!");// Stop the serviceConsole.Write("Service stopping...");service.Stop();Console.WriteLine("Done!");}}}

Performance

Here comes several communication scenarios with timing measurements.

Benchmark environment is the following:

CPU architecutre: Intel(R) Core(TM) i7-4790K CPU @ 4.00GHz
CPU logical cores: 8
CPU physical cores: 4
CPU clock speed: 3.998 GHz
CPU Hyper-Threading: enabled
RAM total: 31.962 GiB
RAM free: 21.623 GiB
OS version: Microsoft Windows 8 Enterprise Edition (build 9200), 64-bit
OS bits: 64-bit
Process bits: 64-bit
Process configuaraion: release

Benchmark: Round-Trip

Round-trip

This scenario sends lots of messages from several clients to a server. The server responses to each message and resend the similar response to the client. The benchmark measures total Round-trip time to send all messages and receive all responses, messages & data throughput, count of errors.

TCP echo server

Server address: 127.0.0.1
Server port: 1111
Working threads: 1
Working clients: 1
Messages to send: 1000000
Message size: 32
Errors: 0
Round-trip time: 3.893 s
Total data: 30.530 MiB
Total messages: 1000000
Data throughput: 7.858 MiB/s
Message latency: 3.893 mcs
Message throughput: 256842 msg/s
Server address: 127.0.0.1
Server port: 1111
Working threads: 4
Working clients: 100
Messages to send: 1000000
Message size: 32
Errors: 0
Round-trip time: 1.557 s
Total data: 30.518 MiB
Total messages: 999632
Data throughput: 19.597 MiB/s
Message latency: 1.558 mcs
Message throughput: 641705 msg/s

SSL echo server

Server address: 127.0.0.1
Server port: 2222
Working threads: 1
Working clients: 1
Messages to send: 1000000
Message size: 32
Errors: 0
Round-trip time: 7.201 s
Total data: 30.530 MiB
Total messages: 1000000
Data throughput: 4.243 MiB/s
Message latency: 7.201 mcs
Message throughput: 138858 msg/s
Server address: 127.0.0.1
Server port: 2222
Working threads: 4
Working clients: 100
Messages to send: 1000000
Message size: 32
Errors: 0
Round-trip time: 4.365 s
Total data: 30.328 MiB
Total messages: 993547
Data throughput: 6.968 MiB/s
Message latency: 4.393 mcs
Message throughput: 227600 msg/s

UDP echo server

Server address: 127.0.0.1
Server port: 3333
Working threads: 1
Working clients: 1
Messages to send: 1000000
Message size: 32
Errors: 0
Round-trip time: 22.071 s
Total data: 30.530 MiB
Total messages: 1000000
Data throughput: 1.391 MiB/s
Message latency: 22.071 mcs
Message throughput: 45306 msg/s
Server address: 127.0.0.1
Server port: 3333
Working threads: 4
Working clients: 100
Messages to send: 1000000
Message size: 32
Errors: 0
Round-trip time: 6.086 s
Total data: 30.512 MiB
Total messages: 999471
Data throughput: 5.011 MiB/s
Message latency: 6.090 mcs
Message throughput: 164201 msg/s

Benchmark: Multicast

Multicast

In this scenario server multicasts messages to all connected clients. The benchmark counts total messages received by all clients for all the working time and measures messages & data throughput, count of errors.

TCP multicast server

Server address: 127.0.0.1
Server port: 1111
Working threads: 1
Working clients: 1
Message size: 32
Errors: 0
Multicast time: 10.002 s
Total data: 970.554 MiB
Total messages: 31802690
Data throughput: 97.027 MiB/s
Message latency: 314 ns
Message throughput: 3179388 msg/s
Server address: 127.0.0.1
Server port: 1111
Working threads: 4
Working clients: 100
Message size: 32
Errors: 0
Multicast time: 10.007 s
Total data: 3.442 GiB
Total messages: 115147638
Data throughput: 351.135 MiB/s
Message latency: 86 ns
Message throughput: 11505891 msg/s

SSL multicast server

Server address: 127.0.0.1
Server port: 2222
Working threads: 1
Working clients: 1
Message size: 32
Errors: 0
Multicast time: 10.011 s
Total data: 458.031 MiB
Total messages: 15008762
Data throughput: 45.769 MiB/s
Message latency: 667 ns
Message throughput: 1499196 msg/s
Server address: 127.0.0.1
Server port: 2222
Working threads: 4
Working clients: 100
Message size: 32
Errors: 0
Multicast time: 10.350 s
Total data: 3.082 GiB
Total messages: 103351505
Data throughput: 304.726 MiB/s
Message latency: 100 ns
Message throughput: 9984724 msg/s

UDP multicast server

Server address: 239.255.0.1
Server port: 3333
Working threads: 1
Working clients: 1
Message size: 32
Errors: 0
Multicast time: 10.004 s
Total data: 19.644 MiB
Total messages: 643205
Data throughput: 1.985 MiB/s
Message latency: 15.553 mcs
Message throughput: 64292 msg/s
Server address: 239.255.0.1
Server port: 3333
Working threads: 4
Working clients: 100
Message size: 32
Errors: 0
Multicast time: 10.007 s
Total data: 78.498 MiB
Total messages: 2571847
Data throughput: 7.862 MiB/s
Message latency: 3.891 mcs
Message throughput: 256982 msg/s

OpenSSL certificates

In order to create OpenSSL based server and client you should prepare a set of SSL certificates. Here comes several steps to get a self-signed set of SSL certificates for testing purposes:

Certificate Authority

  • Create CA private key
openssl genrsa -des3 -passout pass:qwerty -out ca-secret.key 4096
  • Remove passphrase
openssl rsa -passin pass:qwerty -in ca-secret.key -out ca.key
  • Create CA self-signed certificate
openssl req -new -x509 -days 3650 -subj '/C=BY/ST=Belarus/L=Minsk/O=Example root CA/OU=Example CA unit/CN=example.com' -key ca.key -out ca.crt -config openssl.cfg
  • Convert CA self-signed certificate to PKCS
openssl pkcs12 -clcerts -export -passout pass:qwerty -in ca.crt -inkey ca.key -out ca.p12
  • Convert CA self-signed certificate to PEM
openssl pkcs12 -clcerts -passin pass:qwerty -passout pass:qwerty -in ca.p12 -out ca.pem

SSL Server certificate

  • Create private key for the server
openssl genrsa -des3 -passout pass:qwerty -out server-secret.key 4096
  • Remove passphrase
openssl rsa -passin pass:qwerty -in server-secret.key -out server.key
  • Create CSR for the server
openssl req -new -subj '/C=BY/ST=Belarus/L=Minsk/O=Example server/OU=Example server unit/CN=server.example.com' -key server.key -out server.csr -config openssl.cfg
  • Create certificate for the server
openssl x509 -req -days 3650 -in server.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out server.crt
  • Convert the server certificate to PKCS
openssl pkcs12 -clcerts -export -passout pass:qwerty -in server.crt -inkey server.key -out server.p12
  • Convert the server certificate to PEM
openssl pkcs12 -clcerts -passin pass:qwerty -passout pass:qwerty -in server.p12 -out server.pem

SSL Client certificate

  • Create private key for the client
openssl genrsa -des3 -passout pass:qwerty -out client-secret.key 4096
  • Remove passphrase
openssl rsa -passin pass:qwerty -in client-secret.key -out client.key
  • Create CSR for the client
openssl req -new -subj '/C=BY/ST=Belarus/L=Minsk/O=Example client/OU=Example client unit/CN=client.example.com' -key client.key -out client.csr -config openssl.cfg
  • Create the client certificate
openssl x509 -req -days 3650 -in client.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out client.crt
  • Convert the client certificate to PKCS
openssl pkcs12 -clcerts -export -passout pass:qwerty -in client.crt -inkey client.key -out client.p12
  • Convert the client certificate to PEM
openssl pkcs12 -clcerts -passin pass:qwerty -passout pass:qwerty -in client.p12 -out client.pem

Diffie-Hellman key exchange

  • Create DH parameters
openssl dhparam -out dh4096.pem 4096

About

Ultra fast and low latency asynchronous socket server & client C# .NET Core library with support TCP, SSL, UDP protocols and 10K connections problem solution

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

NETCoreServer

Windows build status

Ultra fast and low latency asynchronous socket server & client C# .NET Core library with support TCP, SSL, UDP protocols and 10K connections problem solution.

NETCoreServer documentation
NETCoreServer downloads

Contents

Features

Requirements

How to build?

Setup repository

git clone https://github.com/chronoxor/NETCoreServer.git
cd NETCoreServer

Windows (Visual Studio)

Open and build NETCoreServer.sln or run the build script:

cd build
vs.bat

The build script will create "release" directory with zip files:

  • NETCoreServer.zip - C# Server assembly
  • Benchmarks.zip - C# Server benchmarks
  • Examples.zip - C# Server examples

Examples

Example: Asio timer

Here comes the example of Asio timer. It can be used to wait for some action in future with providing absolute time or relative time span. Asio timer can be used in synchronous or asynchronous modes.

usingSystem;usingSystem.Threading;usingNETCoreServer;namespaceAsioTimer{classAsioTimer:Timer{publicAsioTimer(Serviceservice):base(service){}protectedoverridevoidOnTimer(boolcanceled){Console.WriteLine("Asio timer "+(canceled?"canceled":"expired"));}protectedoverridevoidOnError(interror,stringcategory,stringmessage){Console.WriteLine($"Asio timer caught an error with code {error} and category '{category}': {message}");}}classProgram{staticvoidMain(){// Create a new servicevarservice=newService();// Start the serviceConsole.Write("Service starting...");service.Start();Console.WriteLine("Done!");// Create a new Asio timervartimer=newAsioTimer(service);// Setup and synchronously wait for the timertimer.Setup(DateTime.UtcNow.AddSeconds(1));timer.WaitSync();// Setup and asynchronously wait for the timertimer.Setup(TimeSpan.FromSeconds(1));timer.WaitAsync();// Wait for a while...Thread.Sleep(2000);// Setup and asynchronously wait for the timertimer.Setup(TimeSpan.FromSeconds(1));timer.WaitAsync();// Wait for a while...Thread.Sleep(500);// Cancel the timertimer.Cancel();// Wait for a while...Thread.Sleep(500);// Stop the serviceConsole.Write("Service stopping...");service.Stop();Console.WriteLine("Done!");}}}

Output of the above example is the following:

Service starting...Done!
Asio timer expired
Asio timer canceled
Service stopping...Done!

Example: TCP chat server

Here comes the example of the TCP chat server. It handles multiple TCP client sessions and multicast received message from any session to all ones. Also it is possible to send admin message directly from the server.

usingSystem;usingSystem.Text;usingNETCoreServer;namespaceTcpChatServer{classChatSession:TcpSession{publicChatSession(TcpServerserver):base(server){}protectedoverridevoidOnConnected(){Console.WriteLine($"Chat TCP session with Id {Id} connected!");// Send invite messagestringmessage="Hello from TCP chat! Please send a message or '!' to disconnect the client!";Send(message);}protectedoverridevoidOnDisconnected(){Console.WriteLine($"Chat TCP session with Id {Id} disconnected!");}protectedoverridevoidOnReceived(byte[]buffer){stringmessage=Encoding.UTF8.GetString(buffer);Console.WriteLine("Incoming: "+message);// Multicast message to all connected sessionsServer.Multicast(message);// If the buffer starts with '!' the disconnect the current sessionif(message=="!")Disconnect();}protectedoverridevoidOnError(interror,stringcategory,stringmessage){Console.WriteLine($"Chat TCP session caught an error with code {error} and category '{category}': {message}");}}classChatServer:TcpServer{publicChatServer(Serviceservice,InternetProtocolprotocol,intport):base(service,protocol,port){}protectedoverrideTcpSessionCreateSession(){returnnewChatSession(this);}protectedoverridevoidOnError(interror,stringcategory,stringmessage){Console.WriteLine($"Chat TCP server caught an error with code {error} and category '{category}': {message}");}}classProgram{staticvoidMain(string[]args){// TCP server portintport=1111;if(args.Length>0)port=int.Parse(args[0]);Console.WriteLine($"TCP server port: {port}");// Create a new servicevarservice=newService();// Start the serviceConsole.Write("Service starting...");service.Start();Console.WriteLine("Done!");// Create a new TCP chat servervarserver=newChatServer(service,InternetProtocol.IPv4,port);// Start the serverConsole.Write("Server starting...");server.Start();Console.WriteLine("Done!");Console.WriteLine("Press Enter to stop the server or '!' to restart the server...");// Perform text inputfor(;;){stringline=Console.ReadLine();if(line==String.Empty)break;// Restart the serverif(line=="!"){Console.Write("Server restarting...");server.Restart();Console.WriteLine("Done!");continue;}// Multicast admin message to all sessionsline="(admin) "+line;server.Multicast(line);}// Stop the serverConsole.Write("Server stopping...");server.Stop();Console.WriteLine("Done!");// Stop the serviceConsole.Write("Service stopping...");service.Stop();Console.WriteLine("Done!");}}}

Example: TCP chat client

Here comes the example of the TCP chat client. It connects to the TCP chat server and allows to send message to it and receive new messages.

usingSystem;usingSystem.Text;usingSystem.Threading;usingNETCoreServer;namespaceTcpChatClient{classChatClient:TcpClient{publicChatClient(Serviceservice,stringaddress,intport):base(service,address,port){}publicvoidDisconnectAndStop(){_stop=true;Disconnect();while(IsConnected)Thread.Yield();}protectedoverridevoidOnConnected(){Console.WriteLine($"Chat TCP client connected a new session with Id {Id}");}protectedoverridevoidOnDisconnected(){Console.WriteLine($"Chat TCP client disconnected a session with Id {Id}");// Wait for a while...Thread.Sleep(1000);// Try to connect againif(!_stop)Connect();}protectedoverridevoidOnReceived(byte[]buffer){Console.WriteLine(Encoding.UTF8.GetString(buffer));}protectedoverridevoidOnError(interror,stringcategory,stringmessage){Console.WriteLine($"Chat TCP client caught an error with code {error} and category '{category}': {message}");}privatebool_stop;}classProgram{staticvoidMain(string[]args){// TCP server addressstringaddress="127.0.0.1";if(args.Length>0)address=args[0];// TCP server portintport=1111;if(args.Length>1)port=int.Parse(args[1]);Console.WriteLine($"TCP server address: {address}");Console.WriteLine($"TCP server port: {port}");// Create a new servicevarservice=newService();// Start the serviceConsole.Write("Service starting...");service.Start();Console.WriteLine("Done!");// Create a new TCP chat clientvarclient=newChatClient(service,address,port);// Connect the clientConsole.Write("Client connecting...");client.Connect();Console.WriteLine("Done!");Console.WriteLine("Press Enter to stop the client or '!' to reconnect the client...");// Perform text inputfor(;;){stringline=Console.ReadLine();if(line==String.Empty)break;// Disconnect the clientif(line=="!"){Console.Write("Client disconnecting...");client.Disconnect();Console.WriteLine("Done!");continue;}// Send the entered text to the chat serverclient.Send(line);}// Disconnect the clientConsole.Write("Client disconnecting...");client.DisconnectAndStop();Console.WriteLine("Done!");// Stop the serviceConsole.Write("Service stopping...");service.Stop();Console.WriteLine("Done!");}}}

Example: SSL chat server

Here comes the example of the SSL chat server. It handles multiple SSL client sessions and multicast received message from any session to all ones. Also it is possible to send admin message directly from the server.

This example is very similar to the TCP one except the code that prepares SSL context and handshake handler.

usingSystem;usingSystem.Text;usingNETCoreServer;namespaceSslChatServer{classChatSession:SslSession{publicChatSession(SslServerserver):base(server){}protectedoverridevoidOnConnected(){Console.WriteLine($"Chat SSL session with Id {Id} connected!");// Send invite messagestringmessage="Hello from SSL chat! Please send a message or '!' to disconnect the client!";Send(message);}protectedoverridevoidOnDisconnected(){Console.WriteLine($"Chat SSL session with Id {Id} disconnected!");}protectedoverridevoidOnReceived(byte[]buffer){stringmessage=Encoding.UTF8.GetString(buffer);Console.WriteLine("Incoming: "+message);// Multicast message to all connected sessionsServer.Multicast(message);// If the buffer starts with '!' the disconnect the current sessionif(message=="!")Disconnect();}protectedoverridevoidOnError(interror,stringcategory,stringmessage){Console.WriteLine($"Chat SSL session caught an error with code {error} and category '{category}': {message}");}}classChatServer:SslServer{publicChatServer(Serviceservice,SslContextcontext,InternetProtocolprotocol,intport):base(service,context,protocol,port){}protectedoverrideSslSessionCreateSession(){returnnewChatSession(this);}protectedoverridevoidOnError(interror,stringcategory,stringmessage){Console.WriteLine($"Chat SSL server caught an error with code {error} and category '{category}': {message}");}}classProgram{staticvoidMain(string[]args){// SSL server portintport=2222;if(args.Length>0)port=int.Parse(args[0]);Console.WriteLine($"SSL server port: {port}");// Create a new servicevarservice=newService();// Start the serviceConsole.Write("Service starting...");service.Start();Console.WriteLine("Done!");// Create and prepare a new SSL server contextvarcontext=newSslContext(SslMethod.TLSV12);context.SetPassword("qwerty");context.UseCertificateChainFile("../../../../Tools/certificates/server.pem");context.UsePrivateKeyFile("../../../../Tools/certificates/server.pem",SslFileFormat.PEM);context.UseTmpDHFile("../../../../Tools/certificates/dh4096.pem");// Create a new SSL chat servervarserver=newChatServer(service,context,InternetProtocol.IPv4,port);// Start the serverConsole.Write("Server starting...");server.Start();Console.WriteLine("Done!");Console.WriteLine("Press Enter to stop the server or '!' to restart the server...");// Perform text inputfor(;;){stringline=Console.ReadLine();if(line==String.Empty)break;// Restart the serverif(line=="!"){Console.Write("Server restarting...");server.Restart();Console.WriteLine("Done!");continue;}// Multicast admin message to all sessionsline="(admin) "+line;server.Multicast(line);}// Stop the serverConsole.Write("Server stopping...");server.Stop();Console.WriteLine("Done!");// Stop the serviceConsole.Write("Service stopping...");service.Stop();Console.WriteLine("Done!");}}}

Example: SSL chat client

Here comes the example of the SSL chat client. It connects to the SSL chat server and allows to send message to it and receive new messages.

This example is very similar to the TCP one except the code that prepares SSL context and handshake handler.

usingSystem;usingSystem.Text;usingSystem.Threading;usingNETCoreServer;namespaceSslChatClient{classChatClient:SslClient{publicChatClient(Serviceservice,SslContextcontext,stringaddress,intport):base(service,context,address,port){}publicvoidDisconnectAndStop(){_stop=true;Disconnect();while(IsConnected)Thread.Yield();}protectedoverridevoidOnConnected(){Console.WriteLine($"Chat SSL client connected a new session with Id {Id}");}protectedoverridevoidOnDisconnected(){Console.WriteLine($"Chat SSL client disconnected a session with Id {Id}");// Wait for a while...Thread.Sleep(1000);// Try to connect againif(!_stop)Connect();}protectedoverridevoidOnReceived(byte[]buffer){Console.WriteLine(Encoding.UTF8.GetString(buffer));}protectedoverridevoidOnError(interror,stringcategory,stringmessage){Console.WriteLine($"Chat SSL client caught an error with code {error} and category '{category}': {message}");}privatebool_stop;}classProgram{staticvoidMain(string[]args){// SSL server addressstringaddress="127.0.0.1";if(args.Length>0)address=args[0];// SSL server portintport=2222;if(args.Length>1)port=int.Parse(args[1]);Console.WriteLine($"SSL server address: {address}");Console.WriteLine($"SSL server port: {port}");// Create a new servicevarservice=newService();// Start the serviceConsole.Write("Service starting...");service.Start();Console.WriteLine("Done!");// Create and prepare a new SSL client contextvarcontext=newSslContext(SslMethod.TLSV12);context.SetVerifyMode(SslVerifyMode.VerifyPeer);context.LoadVerifyFile("../../../../Tools/certificates/ca.pem");// Create a new SSL chat clientvarclient=newChatClient(service,context,address,port);// Connect the clientConsole.Write("Client connecting...");client.Connect();Console.WriteLine("Done!");Console.WriteLine("Press Enter to stop the client or '!' to reconnect the client...");// Perform text inputfor(;;){stringline=Console.ReadLine();if(line==String.Empty)break;// Disconnect the clientif(line=="!"){Console.Write("Client disconnecting...");client.Disconnect();Console.WriteLine("Done!");continue;}// Send the entered text to the chat serverclient.Send(line);}// Disconnect the clientConsole.Write("Client disconnecting...");client.DisconnectAndStop();Console.WriteLine("Done!");// Stop the serviceConsole.Write("Service stopping...");service.Stop();Console.WriteLine("Done!");}}}

Example: UDP echo server

Here comes the example of the UDP echo server. It receives a datagram mesage from any UDP client and resend it back without any changes.

usingSystem;usingSystem.Text;usingNETCoreServer;namespaceUdpEchoServer{classEchoServer:UdpServer{publicEchoServer(Serviceservice,InternetProtocolprotocol,intport):base(service,protocol,port){}protectedoverridevoidOnReceived(UdpEndpointendpoint,byte[]buffer){Console.WriteLine("Incoming: "+Encoding.UTF8.GetString(buffer));// Echo the message back to the senderSend(endpoint,buffer);}protectedoverridevoidOnError(interror,stringcategory,stringmessage){Console.WriteLine($"Echo UDP server caught an error with code {error} and category '{category}': {message}");}}classProgram{staticvoidMain(string[]args){// UDP server portintport=3333;if(args.Length>0)port=int.Parse(args[0]);Console.WriteLine($"UDP server port: {port}");// Create a new servicevarservice=newService();// Start the serviceConsole.Write("Service starting...");service.Start();Console.WriteLine("Done!");// Create a new UDP echo servervarserver=newEchoServer(service,InternetProtocol.IPv4,port);// Start the serverConsole.Write("Server starting...");server.Start();Console.WriteLine("Done!");Console.WriteLine("Press Enter to stop the server or '!' to restart the server...");// Perform text inputfor(;;){stringline=Console.ReadLine();if(line==String.Empty)break;// Restart the serverif(line=="!"){Console.Write("Server restarting...");server.Restart();Console.WriteLine("Done!");}}// Stop the serverConsole.Write("Server stopping...");server.Stop();Console.WriteLine("Done!");// Stop the serviceConsole.Write("Service stopping...");service.Stop();Console.WriteLine("Done!");}}}

Example: UDP echo client

Here comes the example of the UDP echo client. It sends user datagram message to UDP server and listen for response.

usingSystem;usingSystem.Text;usingSystem.Threading;usingNETCoreServer;namespaceUdpEchoClient{classEchoClient:UdpClient{publicEchoClient(Serviceservice,stringaddress,intport):base(service,address,port){}publicvoidDisconnectAndStop(){_stop=true;Disconnect();while(IsConnected)Thread.Yield();}protectedoverridevoidOnConnected(){Console.WriteLine($"Echo UDP client connected a new session with Id {Id}");}protectedoverridevoidOnDisconnected(){Console.WriteLine($"Echo UDP client disconnected a session with Id {Id}");// Wait for a while...Thread.Sleep(1000);// Try to connect againif(!_stop)Connect();}protectedoverridevoidOnReceived(UdpEndpointendpoint,byte[]buffer){Console.WriteLine("Incoming: "+Encoding.UTF8.GetString(buffer));}protectedoverridevoidOnError(interror,stringcategory,stringmessage){Console.WriteLine($"Echo UDP client caught an error with code {error} and category '{category}': {message}");}privatebool_stop;}classProgram{staticvoidMain(string[]args){// UDP server addressstringaddress="127.0.0.1";if(args.Length>0)address=args[0];// UDP server portintport=3333;if(args.Length>1)port=int.Parse(args[1]);Console.WriteLine($"UDP server address: {address}");Console.WriteLine($"UDP server port: {port}");// Create a new servicevarservice=newService();// Start the serviceConsole.Write("Service starting...");service.Start();Console.WriteLine("Done!");// Create a new TCP chat clientvarclient=newEchoClient(service,address,port);// Connect the clientConsole.Write("Client connecting...");client.Connect();Console.WriteLine("Done!");Console.WriteLine("Press Enter to stop the client or '!' to reconnect the client...");// Perform text inputfor(;;){stringline=Console.ReadLine();if(line==String.Empty)break;// Disconnect the clientif(line=="!"){Console.Write("Client disconnecting...");client.Disconnect();Console.WriteLine("Done!");continue;}// Send the entered text to the chat serverclient.Send(line);}// Disconnect the clientConsole.Write("Client disconnecting...");client.DisconnectAndStop();Console.WriteLine("Done!");// Stop the serviceConsole.Write("Service stopping...");service.Stop();Console.WriteLine("Done!");}}}

Example: UDP multicast server

Here comes the example of the UDP multicast server. It use multicast IP address to multicast datagram messages to all client that joined corresponding UDP multicast group.

usingSystem;usingSystem.Text;usingNETCoreServer;namespaceUdpMulticastServer{classMulticastServer:UdpServer{publicMulticastServer(Serviceservice,InternetProtocolprotocol,intport):base(service,protocol,port){}protectedoverridevoidOnError(interror,stringcategory,stringmessage){Console.WriteLine($"Multicast UDP server caught an error with code {error} and category '{category}': {message}");}}classProgram{staticvoidMain(string[]args){// UDP multicast addressstringmulticastAddress="239.255.0.1";if(args.Length>0)multicastAddress=args[0];// UDP multicast portintmulticastPort=3334;if(args.Length>1)multicastPort=int.Parse(args[1]);Console.WriteLine($"UDP multicast address: {multicastAddress}");Console.WriteLine($"UDP multicast port: {multicastPort}");// Create a new servicevarservice=newService();// Start the serviceConsole.Write("Service starting...");service.Start();Console.WriteLine("Done!");// Create a new UDP multicast servervarserver=newMulticastServer(service,InternetProtocol.IPv4,0);// Start the multicast serverConsole.Write("Server starting...");server.Start(multicastAddress,multicastPort);Console.WriteLine("Done!");Console.WriteLine("Press Enter to stop the server or '!' to restart the server...");// Perform text inputfor(;;){stringline=Console.ReadLine();if(line==String.Empty)break;// Restart the serverif(line=="!"){Console.Write("Server restarting...");server.Restart();Console.WriteLine("Done!");continue;}// Multicast admin message to all sessionsline="(admin) "+line;server.Multicast(line);}// Stop the serverConsole.Write("Server stopping...");server.Stop();Console.WriteLine("Done!");// Stop the serviceConsole.Write("Service stopping...");service.Stop();Console.WriteLine("Done!");}}}

Example: UDP multicast client

Here comes the example of the UDP multicast client. It use multicast IP address and joins UDP multicast group in order to receive multicasted datagram messages from UDP server.

usingSystem;usingSystem.Text;usingSystem.Threading;usingNETCoreServer;namespaceUdpMulticastClient{classMulticastClient:UdpClient{publicstringMulticast;publicMulticastClient(Serviceservice,stringaddress,intport):base(service,address,port){}publicvoidDisconnectAndStop(){_stop=true;Disconnect();while(IsConnected)Thread.Yield();}protectedoverridevoidOnConnected(){Console.WriteLine($"Multicast UDP client connected a new session with Id {Id}");// Join UDP multicast groupJoinMulticastGroup(Multicast);}protectedoverridevoidOnDisconnected(){Console.WriteLine($"Multicast UDP client disconnected a session with Id {Id}");// Wait for a while...Thread.Sleep(1000);// Try to connect againif(!_stop)Connect();}protectedoverridevoidOnReceived(UdpEndpointendpoint,byte[]buffer){Console.WriteLine("Incoming: "+Encoding.UTF8.GetString(buffer));}protectedoverridevoidOnError(interror,stringcategory,stringmessage){Console.WriteLine($"Multicast UDP client caught an error with code {error} and category '{category}': {message}");}privatebool_stop;}classProgram{staticvoidMain(string[]args){// UDP listen addressstringlistenAddress="0.0.0.0";if(args.Length>0)listenAddress=args[0];// UDP multicast addressstringmulticastAddress="239.255.0.1";if(args.Length>1)multicastAddress=args[1];// UDP multicast portintmulticastPort=3334;if(args.Length>2)multicastPort=int.Parse(args[2]);Console.WriteLine($"UDP listen address: {listenAddress}");Console.WriteLine($"UDP multicast address: {multicastAddress}");Console.WriteLine($"UDP multicast port: {multicastPort}");// Create a new servicevarservice=newService();// Start the serviceConsole.Write("Service starting...");service.Start();Console.WriteLine("Done!");// Create a new TCP chat clientvarclient=newMulticastClient(service,listenAddress,multicastPort);client.SetupMulticast(true);client.Multicast=multicastAddress;// Connect the clientConsole.Write("Client connecting...");client.Connect();Console.WriteLine("Done!");Console.WriteLine("Press Enter to stop the client or '!' to reconnect the client...");// Perform text inputfor(;;){stringline=Console.ReadLine();if(line==String.Empty)break;// Disconnect the clientif(line=="!"){Console.Write("Client disconnecting...");client.Disconnect();Console.WriteLine("Done!");continue;}// Send the entered text to the chat serverclient.Send(line);}// Disconnect the clientConsole.Write("Client disconnecting...");client.DisconnectAndStop();Console.WriteLine("Done!");// Stop the serviceConsole.Write("Service stopping...");service.Stop();Console.WriteLine("Done!");}}}

Performance

Here comes several communication scenarios with timing measurements.

Benchmark environment is the following:

CPU architecutre: Intel(R) Core(TM) i7-4790K CPU @ 4.00GHz
CPU logical cores: 8
CPU physical cores: 4
CPU clock speed: 3.998 GHz
CPU Hyper-Threading: enabled
RAM total: 31.962 GiB
RAM free: 21.623 GiB
OS version: Microsoft Windows 8 Enterprise Edition (build 9200), 64-bit
OS bits: 64-bit
Process bits: 64-bit
Process configuaraion: release

Benchmark: Round-Trip

Round-trip

This scenario sends lots of messages from several clients to a server. The server responses to each message and resend the similar response to the client. The benchmark measures total Round-trip time to send all messages and receive all responses, messages & data throughput, count of errors.

TCP echo server

Server address: 127.0.0.1
Server port: 1111
Working threads: 1
Working clients: 1
Messages to send: 1000000
Message size: 32
Errors: 0
Round-trip time: 3.893 s
Total data: 30.530 MiB
Total messages: 1000000
Data throughput: 7.858 MiB/s
Message latency: 3.893 mcs
Message throughput: 256842 msg/s
Server address: 127.0.0.1
Server port: 1111
Working threads: 4
Working clients: 100
Messages to send: 1000000
Message size: 32
Errors: 0
Round-trip time: 1.557 s
Total data: 30.518 MiB
Total messages: 999632
Data throughput: 19.597 MiB/s
Message latency: 1.558 mcs
Message throughput: 641705 msg/s

SSL echo server

Server address: 127.0.0.1
Server port: 2222
Working threads: 1
Working clients: 1
Messages to send: 1000000
Message size: 32
Errors: 0
Round-trip time: 7.201 s
Total data: 30.530 MiB
Total messages: 1000000
Data throughput: 4.243 MiB/s
Message latency: 7.201 mcs
Message throughput: 138858 msg/s
Server address: 127.0.0.1
Server port: 2222
Working threads: 4
Working clients: 100
Messages to send: 1000000
Message size: 32
Errors: 0
Round-trip time: 4.365 s
Total data: 30.328 MiB
Total messages: 993547
Data throughput: 6.968 MiB/s
Message latency: 4.393 mcs
Message throughput: 227600 msg/s

UDP echo server

Server address: 127.0.0.1
Server port: 3333
Working threads: 1
Working clients: 1
Messages to send: 1000000
Message size: 32
Errors: 0
Round-trip time: 22.071 s
Total data: 30.530 MiB
Total messages: 1000000
Data throughput: 1.391 MiB/s
Message latency: 22.071 mcs
Message throughput: 45306 msg/s
Server address: 127.0.0.1
Server port: 3333
Working threads: 4
Working clients: 100
Messages to send: 1000000
Message size: 32
Errors: 0
Round-trip time: 6.086 s
Total data: 30.512 MiB
Total messages: 999471
Data throughput: 5.011 MiB/s
Message latency: 6.090 mcs
Message throughput: 164201 msg/s

Benchmark: Multicast

Multicast

In this scenario server multicasts messages to all connected clients. The benchmark counts total messages received by all clients for all the working time and measures messages & data throughput, count of errors.

TCP multicast server

Server address: 127.0.0.1
Server port: 1111
Working threads: 1
Working clients: 1
Message size: 32
Errors: 0
Multicast time: 10.002 s
Total data: 970.554 MiB
Total messages: 31802690
Data throughput: 97.027 MiB/s
Message latency: 314 ns
Message throughput: 3179388 msg/s
Server address: 127.0.0.1
Server port: 1111
Working threads: 4
Working clients: 100
Message size: 32
Errors: 0
Multicast time: 10.007 s
Total data: 3.442 GiB
Total messages: 115147638
Data throughput: 351.135 MiB/s
Message latency: 86 ns
Message throughput: 11505891 msg/s

SSL multicast server

Server address: 127.0.0.1
Server port: 2222
Working threads: 1
Working clients: 1
Message size: 32
Errors: 0
Multicast time: 10.011 s
Total data: 458.031 MiB
Total messages: 15008762
Data throughput: 45.769 MiB/s
Message latency: 667 ns
Message throughput: 1499196 msg/s
Server address: 127.0.0.1
Server port: 2222
Working threads: 4
Working clients: 100
Message size: 32
Errors: 0
Multicast time: 10.350 s
Total data: 3.082 GiB
Total messages: 103351505
Data throughput: 304.726 MiB/s
Message latency: 100 ns
Message throughput: 9984724 msg/s

UDP multicast server

Server address: 239.255.0.1
Server port: 3333
Working threads: 1
Working clients: 1
Message size: 32
Errors: 0
Multicast time: 10.004 s
Total data: 19.644 MiB
Total messages: 643205
Data throughput: 1.985 MiB/s
Message latency: 15.553 mcs
Message throughput: 64292 msg/s
Server address: 239.255.0.1
Server port: 3333
Working threads: 4
Working clients: 100
Message size: 32
Errors: 0
Multicast time: 10.007 s
Total data: 78.498 MiB
Total messages: 2571847
Data throughput: 7.862 MiB/s
Message latency: 3.891 mcs
Message throughput: 256982 msg/s

OpenSSL certificates

In order to create OpenSSL based server and client you should prepare a set of SSL certificates. Here comes several steps to get a self-signed set of SSL certificates for testing purposes:

Certificate Authority

  • Create CA private key
openssl genrsa -des3 -passout pass:qwerty -out ca-secret.key 4096
  • Remove passphrase
openssl rsa -passin pass:qwerty -in ca-secret.key -out ca.key
  • Create CA self-signed certificate
openssl req -new -x509 -days 3650 -subj '/C=BY/ST=Belarus/L=Minsk/O=Example root CA/OU=Example CA unit/CN=example.com' -key ca.key -out ca.crt -config openssl.cfg
  • Convert CA self-signed certificate to PKCS
openssl pkcs12 -clcerts -export -passout pass:qwerty -in ca.crt -inkey ca.key -out ca.p12
  • Convert CA self-signed certificate to PEM
openssl pkcs12 -clcerts -passin pass:qwerty -passout pass:qwerty -in ca.p12 -out ca.pem

SSL Server certificate

  • Create private key for the server
openssl genrsa -des3 -passout pass:qwerty -out server-secret.key 4096
  • Remove passphrase
openssl rsa -passin pass:qwerty -in server-secret.key -out server.key
  • Create CSR for the server
openssl req -new -subj '/C=BY/ST=Belarus/L=Minsk/O=Example server/OU=Example server unit/CN=server.example.com' -key server.key -out server.csr -config openssl.cfg
  • Create certificate for the server
openssl x509 -req -days 3650 -in server.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out server.crt
  • Convert the server certificate to PKCS
openssl pkcs12 -clcerts -export -passout pass:qwerty -in server.crt -inkey server.key -out server.p12
  • Convert the server certificate to PEM
openssl pkcs12 -clcerts -passin pass:qwerty -passout pass:qwerty -in server.p12 -out server.pem

SSL Client certificate

  • Create private key for the client
openssl genrsa -des3 -passout pass:qwerty -out client-secret.key 4096
  • Remove passphrase
openssl rsa -passin pass:qwerty -in client-secret.key -out client.key
  • Create CSR for the client
openssl req -new -subj '/C=BY/ST=Belarus/L=Minsk/O=Example client/OU=Example client unit/CN=client.example.com' -key client.key -out client.csr -config openssl.cfg
  • Create the client certificate
openssl x509 -req -days 3650 -in client.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out client.crt
  • Convert the client certificate to PKCS
openssl pkcs12 -clcerts -export -passout pass:qwerty -in client.crt -inkey client.key -out client.p12
  • Convert the client certificate to PEM
openssl pkcs12 -clcerts -passin pass:qwerty -passout pass:qwerty -in client.p12 -out client.pem

Diffie-Hellman key exchange

  • Create DH parameters
openssl dhparam -out dh4096.pem 4096

About

Ultra fast and low latency asynchronous socket server & client C# .NET Core library with support TCP, SSL, UDP protocols and 10K connections problem solution

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

NETCoreServer

Windows build status

Ultra fast and low latency asynchronous socket server & client C# .NET Core library with support TCP, SSL, UDP protocols and 10K connections problem solution.

NETCoreServer documentation
NETCoreServer downloads

Contents

Features

Requirements

How to build?

Setup repository

git clone https://github.com/chronoxor/NETCoreServer.git
cd NETCoreServer

Windows (Visual Studio)

Open and build NETCoreServer.sln or run the build script:

cd build
vs.bat

The build script will create "release" directory with zip files:

  • NETCoreServer.zip - C# Server assembly
  • Benchmarks.zip - C# Server benchmarks
  • Examples.zip - C# Server examples

Examples

Example: Asio timer

Here comes the example of Asio timer. It can be used to wait for some action in future with providing absolute time or relative time span. Asio timer can be used in synchronous or asynchronous modes.

usingSystem;usingSystem.Threading;usingNETCoreServer;namespaceAsioTimer{classAsioTimer:Timer{publicAsioTimer(Serviceservice):base(service){}protectedoverridevoidOnTimer(boolcanceled){Console.WriteLine("Asio timer "+(canceled?"canceled":"expired"));}protectedoverridevoidOnError(interror,stringcategory,stringmessage){Console.WriteLine($"Asio timer caught an error with code {error} and category '{category}': {message}");}}classProgram{staticvoidMain(){// Create a new servicevarservice=newService();// Start the serviceConsole.Write("Service starting...");service.Start();Console.WriteLine("Done!");// Create a new Asio timervartimer=newAsioTimer(service);// Setup and synchronously wait for the timertimer.Setup(DateTime.UtcNow.AddSeconds(1));timer.WaitSync();// Setup and asynchronously wait for the timertimer.Setup(TimeSpan.FromSeconds(1));timer.WaitAsync();// Wait for a while...Thread.Sleep(2000);// Setup and asynchronously wait for the timertimer.Setup(TimeSpan.FromSeconds(1));timer.WaitAsync();// Wait for a while...Thread.Sleep(500);// Cancel the timertimer.Cancel();// Wait for a while...Thread.Sleep(500);// Stop the serviceConsole.Write("Service stopping...");service.Stop();Console.WriteLine("Done!");}}}

Output of the above example is the following:

Service starting...Done!
Asio timer expired
Asio timer canceled
Service stopping...Done!

Example: TCP chat server

Here comes the example of the TCP chat server. It handles multiple TCP client sessions and multicast received message from any session to all ones. Also it is possible to send admin message directly from the server.

usingSystem;usingSystem.Text;usingNETCoreServer;namespaceTcpChatServer{classChatSession:TcpSession{publicChatSession(TcpServerserver):base(server){}protectedoverridevoidOnConnected(){Console.WriteLine($"Chat TCP session with Id {Id} connected!");// Send invite messagestringmessage="Hello from TCP chat! Please send a message or '!' to disconnect the client!";Send(message);}protectedoverridevoidOnDisconnected(){Console.WriteLine($"Chat TCP session with Id {Id} disconnected!");}protectedoverridevoidOnReceived(byte[]buffer){stringmessage=Encoding.UTF8.GetString(buffer);Console.WriteLine("Incoming: "+message);// Multicast message to all connected sessionsServer.Multicast(message);// If the buffer starts with '!' the disconnect the current sessionif(message=="!")Disconnect();}protectedoverridevoidOnError(interror,stringcategory,stringmessage){Console.WriteLine($"Chat TCP session caught an error with code {error} and category '{category}': {message}");}}classChatServer:TcpServer{publicChatServer(Serviceservice,InternetProtocolprotocol,intport):base(service,protocol,port){}protectedoverrideTcpSessionCreateSession(){returnnewChatSession(this);}protectedoverridevoidOnError(interror,stringcategory,stringmessage){Console.WriteLine($"Chat TCP server caught an error with code {error} and category '{category}': {message}");}}classProgram{staticvoidMain(string[]args){// TCP server portintport=1111;if(args.Length>0)port=int.Parse(args[0]);Console.WriteLine($"TCP server port: {port}");// Create a new servicevarservice=newService();// Start the serviceConsole.Write("Service starting...");service.Start();Console.WriteLine("Done!");// Create a new TCP chat servervarserver=newChatServer(service,InternetProtocol.IPv4,port);// Start the serverConsole.Write("Server starting...");server.Start();Console.WriteLine("Done!");Console.WriteLine("Press Enter to stop the server or '!' to restart the server...");// Perform text inputfor(;;){stringline=Console.ReadLine();if(line==String.Empty)break;// Restart the serverif(line=="!"){Console.Write("Server restarting...");server.Restart();Console.WriteLine("Done!");continue;}// Multicast admin message to all sessionsline="(admin) "+line;server.Multicast(line);}// Stop the serverConsole.Write("Server stopping...");server.Stop();Console.WriteLine("Done!");// Stop the serviceConsole.Write("Service stopping...");service.Stop();Console.WriteLine("Done!");}}}

Example: TCP chat client

Here comes the example of the TCP chat client. It connects to the TCP chat server and allows to send message to it and receive new messages.

usingSystem;usingSystem.Text;usingSystem.Threading;usingNETCoreServer;namespaceTcpChatClient{classChatClient:TcpClient{publicChatClient(Serviceservice,stringaddress,intport):base(service,address,port){}publicvoidDisconnectAndStop(){_stop=true;Disconnect();while(IsConnected)Thread.Yield();}protectedoverridevoidOnConnected(){Console.WriteLine($"Chat TCP client connected a new session with Id {Id}");}protectedoverridevoidOnDisconnected(){Console.WriteLine($"Chat TCP client disconnected a session with Id {Id}");// Wait for a while...Thread.Sleep(1000);// Try to connect againif(!_stop)Connect();}protectedoverridevoidOnReceived(byte[]buffer){Console.WriteLine(Encoding.UTF8.GetString(buffer));}protectedoverridevoidOnError(interror,stringcategory,stringmessage){Console.WriteLine($"Chat TCP client caught an error with code {error} and category '{category}': {message}");}privatebool_stop;}classProgram{staticvoidMain(string[]args){// TCP server addressstringaddress="127.0.0.1";if(args.Length>0)address=args[0];// TCP server portintport=1111;if(args.Length>1)port=int.Parse(args[1]);Console.WriteLine($"TCP server address: {address}");Console.WriteLine($"TCP server port: {port}");// Create a new servicevarservice=newService();// Start the serviceConsole.Write("Service starting...");service.Start();Console.WriteLine("Done!");// Create a new TCP chat clientvarclient=newChatClient(service,address,port);// Connect the clientConsole.Write("Client connecting...");client.Connect();Console.WriteLine("Done!");Console.WriteLine("Press Enter to stop the client or '!' to reconnect the client...");// Perform text inputfor(;;){stringline=Console.ReadLine();if(line==String.Empty)break;// Disconnect the clientif(line=="!"){Console.Write("Client disconnecting...");client.Disconnect();Console.WriteLine("Done!");continue;}// Send the entered text to the chat serverclient.Send(line);}// Disconnect the clientConsole.Write("Client disconnecting...");client.DisconnectAndStop();Console.WriteLine("Done!");// Stop the serviceConsole.Write("Service stopping...");service.Stop();Console.WriteLine("Done!");}}}

Example: SSL chat server

Here comes the example of the SSL chat server. It handles multiple SSL client sessions and multicast received message from any session to all ones. Also it is possible to send admin message directly from the server.

This example is very similar to the TCP one except the code that prepares SSL context and handshake handler.

usingSystem;usingSystem.Text;usingNETCoreServer;namespaceSslChatServer{classChatSession:SslSession{publicChatSession(SslServerserver):base(server){}protectedoverridevoidOnConnected(){Console.WriteLine($"Chat SSL session with Id {Id} connected!");// Send invite messagestringmessage="Hello from SSL chat! Please send a message or '!' to disconnect the client!";Send(message);}protectedoverridevoidOnDisconnected(){Console.WriteLine($"Chat SSL session with Id {Id} disconnected!");}protectedoverridevoidOnReceived(byte[]buffer){stringmessage=Encoding.UTF8.GetString(buffer);Console.WriteLine("Incoming: "+message);// Multicast message to all connected sessionsServer.Multicast(message);// If the buffer starts with '!' the disconnect the current sessionif(message=="!")Disconnect();}protectedoverridevoidOnError(interror,stringcategory,stringmessage){Console.WriteLine($"Chat SSL session caught an error with code {error} and category '{category}': {message}");}}classChatServer:SslServer{publicChatServer(Serviceservice,SslContextcontext,InternetProtocolprotocol,intport):base(service,context,protocol,port){}protectedoverrideSslSessionCreateSession(){returnnewChatSession(this);}protectedoverridevoidOnError(interror,stringcategory,stringmessage){Console.WriteLine($"Chat SSL server caught an error with code {error} and category '{category}': {message}");}}classProgram{staticvoidMain(string[]args){// SSL server portintport=2222;if(args.Length>0)port=int.Parse(args[0]);Console.WriteLine($"SSL server port: {port}");// Create a new servicevarservice=newService();// Start the serviceConsole.Write("Service starting...");service.Start();Console.WriteLine("Done!");// Create and prepare a new SSL server contextvarcontext=newSslContext(SslMethod.TLSV12);context.SetPassword("qwerty");context.UseCertificateChainFile("../../../../Tools/certificates/server.pem");context.UsePrivateKeyFile("../../../../Tools/certificates/server.pem",SslFileFormat.PEM);context.UseTmpDHFile("../../../../Tools/certificates/dh4096.pem");// Create a new SSL chat servervarserver=newChatServer(service,context,InternetProtocol.IPv4,port);// Start the serverConsole.Write("Server starting...");server.Start();Console.WriteLine("Done!");Console.WriteLine("Press Enter to stop the server or '!' to restart the server...");// Perform text inputfor(;;){stringline=Console.ReadLine();if(line==String.Empty)break;// Restart the serverif(line=="!"){Console.Write("Server restarting...");server.Restart();Console.WriteLine("Done!");continue;}// Multicast admin message to all sessionsline="(admin) "+line;server.Multicast(line);}// Stop the serverConsole.Write("Server stopping...");server.Stop();Console.WriteLine("Done!");// Stop the serviceConsole.Write("Service stopping...");service.Stop();Console.WriteLine("Done!");}}}

Example: SSL chat client

Here comes the example of the SSL chat client. It connects to the SSL chat server and allows to send message to it and receive new messages.

This example is very similar to the TCP one except the code that prepares SSL context and handshake handler.

usingSystem;usingSystem.Text;usingSystem.Threading;usingNETCoreServer;namespaceSslChatClient{classChatClient:SslClient{publicChatClient(Serviceservice,SslContextcontext,stringaddress,intport):base(service,context,address,port){}publicvoidDisconnectAndStop(){_stop=true;Disconnect();while(IsConnected)Thread.Yield();}protectedoverridevoidOnConnected(){Console.WriteLine($"Chat SSL client connected a new session with Id {Id}");}protectedoverridevoidOnDisconnected(){Console.WriteLine($"Chat SSL client disconnected a session with Id {Id}");// Wait for a while...Thread.Sleep(1000);// Try to connect againif(!_stop)Connect();}protectedoverridevoidOnReceived(byte[]buffer){Console.WriteLine(Encoding.UTF8.GetString(buffer));}protectedoverridevoidOnError(interror,stringcategory,stringmessage){Console.WriteLine($"Chat SSL client caught an error with code {error} and category '{category}': {message}");}privatebool_stop;}classProgram{staticvoidMain(string[]args){// SSL server addressstringaddress="127.0.0.1";if(args.Length>0)address=args[0];// SSL server portintport=2222;if(args.Length>1)port=int.Parse(args[1]);Console.WriteLine($"SSL server address: {address}");Console.WriteLine($"SSL server port: {port}");// Create a new servicevarservice=newService();// Start the serviceConsole.Write("Service starting...");service.Start();Console.WriteLine("Done!");// Create and prepare a new SSL client contextvarcontext=newSslContext(SslMethod.TLSV12);context.SetVerifyMode(SslVerifyMode.VerifyPeer);context.LoadVerifyFile("../../../../Tools/certificates/ca.pem");// Create a new SSL chat clientvarclient=newChatClient(service,context,address,port);// Connect the clientConsole.Write("Client connecting...");client.Connect();Console.WriteLine("Done!");Console.WriteLine("Press Enter to stop the client or '!' to reconnect the client...");// Perform text inputfor(;;){stringline=Console.ReadLine();if(line==String.Empty)break;// Disconnect the clientif(line=="!"){Console.Write("Client disconnecting...");client.Disconnect();Console.WriteLine("Done!");continue;}// Send the entered text to the chat serverclient.Send(line);}// Disconnect the clientConsole.Write("Client disconnecting...");client.DisconnectAndStop();Console.WriteLine("Done!");// Stop the serviceConsole.Write("Service stopping...");service.Stop();Console.WriteLine("Done!");}}}

Example: UDP echo server

Here comes the example of the UDP echo server. It receives a datagram mesage from any UDP client and resend it back without any changes.

usingSystem;usingSystem.Text;usingNETCoreServer;namespaceUdpEchoServer{classEchoServer:UdpServer{publicEchoServer(Serviceservice,InternetProtocolprotocol,intport):base(service,protocol,port){}protectedoverridevoidOnReceived(UdpEndpointendpoint,byte[]buffer){Console.WriteLine("Incoming: "+Encoding.UTF8.GetString(buffer));// Echo the message back to the senderSend(endpoint,buffer);}protectedoverridevoidOnError(interror,stringcategory,stringmessage){Console.WriteLine($"Echo UDP server caught an error with code {error} and category '{category}': {message}");}}classProgram{staticvoidMain(string[]args){// UDP server portintport=3333;if(args.Length>0)port=int.Parse(args[0]);Console.WriteLine($"UDP server port: {port}");// Create a new servicevarservice=newService();// Start the serviceConsole.Write("Service starting...");service.Start();Console.WriteLine("Done!");// Create a new UDP echo servervarserver=newEchoServer(service,InternetProtocol.IPv4,port);// Start the serverConsole.Write("Server starting...");server.Start();Console.WriteLine("Done!");Console.WriteLine("Press Enter to stop the server or '!' to restart the server...");// Perform text inputfor(;;){stringline=Console.ReadLine();if(line==String.Empty)break;// Restart the serverif(line=="!"){Console.Write("Server restarting...");server.Restart();Console.WriteLine("Done!");}}// Stop the serverConsole.Write("Server stopping...");server.Stop();Console.WriteLine("Done!");// Stop the serviceConsole.Write("Service stopping...");service.Stop();Console.WriteLine("Done!");}}}

Example: UDP echo client

Here comes the example of the UDP echo client. It sends user datagram message to UDP server and listen for response.

usingSystem;usingSystem.Text;usingSystem.Threading;usingNETCoreServer;namespaceUdpEchoClient{classEchoClient:UdpClient{publicEchoClient(Serviceservice,stringaddress,intport):base(service,address,port){}publicvoidDisconnectAndStop(){_stop=true;Disconnect();while(IsConnected)Thread.Yield();}protectedoverridevoidOnConnected(){Console.WriteLine($"Echo UDP client connected a new session with Id {Id}");}protectedoverridevoidOnDisconnected(){Console.WriteLine($"Echo UDP client disconnected a session with Id {Id}");// Wait for a while...Thread.Sleep(1000);// Try to connect againif(!_stop)Connect();}protectedoverridevoidOnReceived(UdpEndpointendpoint,byte[]buffer){Console.WriteLine("Incoming: "+Encoding.UTF8.GetString(buffer));}protectedoverridevoidOnError(interror,stringcategory,stringmessage){Console.WriteLine($"Echo UDP client caught an error with code {error} and category '{category}': {message}");}privatebool_stop;}classProgram{staticvoidMain(string[]args){// UDP server addressstringaddress="127.0.0.1";if(args.Length>0)address=args[0];// UDP server portintport=3333;if(args.Length>1)port=int.Parse(args[1]);Console.WriteLine($"UDP server address: {address}");Console.WriteLine($"UDP server port: {port}");// Create a new servicevarservice=newService();// Start the serviceConsole.Write("Service starting...");service.Start();Console.WriteLine("Done!");// Create a new TCP chat clientvarclient=newEchoClient(service,address,port);// Connect the clientConsole.Write("Client connecting...");client.Connect();Console.WriteLine("Done!");Console.WriteLine("Press Enter to stop the client or '!' to reconnect the client...");// Perform text inputfor(;;){stringline=Console.ReadLine();if(line==String.Empty)break;// Disconnect the clientif(line=="!"){Console.Write("Client disconnecting...");client.Disconnect();Console.WriteLine("Done!");continue;}// Send the entered text to the chat serverclient.Send(line);}// Disconnect the clientConsole.Write("Client disconnecting...");client.DisconnectAndStop();Console.WriteLine("Done!");// Stop the serviceConsole.Write("Service stopping...");service.Stop();Console.WriteLine("Done!");}}}

Example: UDP multicast server

Here comes the example of the UDP multicast server. It use multicast IP address to multicast datagram messages to all client that joined corresponding UDP multicast group.

usingSystem;usingSystem.Text;usingNETCoreServer;namespaceUdpMulticastServer{classMulticastServer:UdpServer{publicMulticastServer(Serviceservice,InternetProtocolprotocol,intport):base(service,protocol,port){}protectedoverridevoidOnError(interror,stringcategory,stringmessage){Console.WriteLine($"Multicast UDP server caught an error with code {error} and category '{category}': {message}");}}classProgram{staticvoidMain(string[]args){// UDP multicast addressstringmulticastAddress="239.255.0.1";if(args.Length>0)multicastAddress=args[0];// UDP multicast portintmulticastPort=3334;if(args.Length>1)multicastPort=int.Parse(args[1]);Console.WriteLine($"UDP multicast address: {multicastAddress}");Console.WriteLine($"UDP multicast port: {multicastPort}");// Create a new servicevarservice=newService();// Start the serviceConsole.Write("Service starting...");service.Start();Console.WriteLine("Done!");// Create a new UDP multicast servervarserver=newMulticastServer(service,InternetProtocol.IPv4,0);// Start the multicast serverConsole.Write("Server starting...");server.Start(multicastAddress,multicastPort);Console.WriteLine("Done!");Console.WriteLine("Press Enter to stop the server or '!' to restart the server...");// Perform text inputfor(;;){stringline=Console.ReadLine();if(line==String.Empty)break;// Restart the serverif(line=="!"){Console.Write("Server restarting...");server.Restart();Console.WriteLine("Done!");continue;}// Multicast admin message to all sessionsline="(admin) "+line;server.Multicast(line);}// Stop the serverConsole.Write("Server stopping...");server.Stop();Console.WriteLine("Done!");// Stop the serviceConsole.Write("Service stopping...");service.Stop();Console.WriteLine("Done!");}}}

Example: UDP multicast client

Here comes the example of the UDP multicast client. It use multicast IP address and joins UDP multicast group in order to receive multicasted datagram messages from UDP server.

usingSystem;usingSystem.Text;usingSystem.Threading;usingNETCoreServer;namespaceUdpMulticastClient{classMulticastClient:UdpClient{publicstringMulticast;publicMulticastClient(Serviceservice,stringaddress,intport):base(service,address,port){}publicvoidDisconnectAndStop(){_stop=true;Disconnect();while(IsConnected)Thread.Yield();}protectedoverridevoidOnConnected(){Console.WriteLine($"Multicast UDP client connected a new session with Id {Id}");// Join UDP multicast groupJoinMulticastGroup(Multicast);}protectedoverridevoidOnDisconnected(){Console.WriteLine($"Multicast UDP client disconnected a session with Id {Id}");// Wait for a while...Thread.Sleep(1000);// Try to connect againif(!_stop)Connect();}protectedoverridevoidOnReceived(UdpEndpointendpoint,byte[]buffer){Console.WriteLine("Incoming: "+Encoding.UTF8.GetString(buffer));}protectedoverridevoidOnError(interror,stringcategory,stringmessage){Console.WriteLine($"Multicast UDP client caught an error with code {error} and category '{category}': {message}");}privatebool_stop;}classProgram{staticvoidMain(string[]args){// UDP listen addressstringlistenAddress="0.0.0.0";if(args.Length>0)listenAddress=args[0];// UDP multicast addressstringmulticastAddress="239.255.0.1";if(args.Length>1)multicastAddress=args[1];// UDP multicast portintmulticastPort=3334;if(args.Length>2)multicastPort=int.Parse(args[2]);Console.WriteLine($"UDP listen address: {listenAddress}");Console.WriteLine($"UDP multicast address: {multicastAddress}");Console.WriteLine($"UDP multicast port: {multicastPort}");// Create a new servicevarservice=newService();// Start the serviceConsole.Write("Service starting...");service.Start();Console.WriteLine("Done!");// Create a new TCP chat clientvarclient=newMulticastClient(service,listenAddress,multicastPort);client.SetupMulticast(true);client.Multicast=multicastAddress;// Connect the clientConsole.Write("Client connecting...");client.Connect();Console.WriteLine("Done!");Console.WriteLine("Press Enter to stop the client or '!' to reconnect the client...");// Perform text inputfor(;;){stringline=Console.ReadLine();if(line==String.Empty)break;// Disconnect the clientif(line=="!"){Console.Write("Client disconnecting...");client.Disconnect();Console.WriteLine("Done!");continue;}// Send the entered text to the chat serverclient.Send(line);}// Disconnect the clientConsole.Write("Client disconnecting...");client.DisconnectAndStop();Console.WriteLine("Done!");// Stop the serviceConsole.Write("Service stopping...");service.Stop();Console.WriteLine("Done!");}}}

Performance

Here comes several communication scenarios with timing measurements.

Benchmark environment is the following:

CPU architecutre: Intel(R) Core(TM) i7-4790K CPU @ 4.00GHz
CPU logical cores: 8
CPU physical cores: 4
CPU clock speed: 3.998 GHz
CPU Hyper-Threading: enabled
RAM total: 31.962 GiB
RAM free: 21.623 GiB
OS version: Microsoft Windows 8 Enterprise Edition (build 9200), 64-bit
OS bits: 64-bit
Process bits: 64-bit
Process configuaraion: release

Benchmark: Round-Trip

Round-trip

This scenario sends lots of messages from several clients to a server. The server responses to each message and resend the similar response to the client. The benchmark measures total Round-trip time to send all messages and receive all responses, messages & data throughput, count of errors.

TCP echo server

Server address: 127.0.0.1
Server port: 1111
Working threads: 1
Working clients: 1
Messages to send: 1000000
Message size: 32
Errors: 0
Round-trip time: 3.893 s
Total data: 30.530 MiB
Total messages: 1000000
Data throughput: 7.858 MiB/s
Message latency: 3.893 mcs
Message throughput: 256842 msg/s
Server address: 127.0.0.1
Server port: 1111
Working threads: 4
Working clients: 100
Messages to send: 1000000
Message size: 32
Errors: 0
Round-trip time: 1.557 s
Total data: 30.518 MiB
Total messages: 999632
Data throughput: 19.597 MiB/s
Message latency: 1.558 mcs
Message throughput: 641705 msg/s

SSL echo server

Server address: 127.0.0.1
Server port: 2222
Working threads: 1
Working clients: 1
Messages to send: 1000000
Message size: 32
Errors: 0
Round-trip time: 7.201 s
Total data: 30.530 MiB
Total messages: 1000000
Data throughput: 4.243 MiB/s
Message latency: 7.201 mcs
Message throughput: 138858 msg/s
Server address: 127.0.0.1
Server port: 2222
Working threads: 4
Working clients: 100
Messages to send: 1000000
Message size: 32
Errors: 0
Round-trip time: 4.365 s
Total data: 30.328 MiB
Total messages: 993547
Data throughput: 6.968 MiB/s
Message latency: 4.393 mcs
Message throughput: 227600 msg/s

UDP echo server

Server address: 127.0.0.1
Server port: 3333
Working threads: 1
Working clients: 1
Messages to send: 1000000
Message size: 32
Errors: 0
Round-trip time: 22.071 s
Total data: 30.530 MiB
Total messages: 1000000
Data throughput: 1.391 MiB/s
Message latency: 22.071 mcs
Message throughput: 45306 msg/s
Server address: 127.0.0.1
Server port: 3333
Working threads: 4
Working clients: 100
Messages to send: 1000000
Message size: 32
Errors: 0
Round-trip time: 6.086 s
Total data: 30.512 MiB
Total messages: 999471
Data throughput: 5.011 MiB/s
Message latency: 6.090 mcs
Message throughput: 164201 msg/s

Benchmark: Multicast

Multicast

In this scenario server multicasts messages to all connected clients. The benchmark counts total messages received by all clients for all the working time and measures messages & data throughput, count of errors.

TCP multicast server

Server address: 127.0.0.1
Server port: 1111
Working threads: 1
Working clients: 1
Message size: 32
Errors: 0
Multicast time: 10.002 s
Total data: 970.554 MiB
Total messages: 31802690
Data throughput: 97.027 MiB/s
Message latency: 314 ns
Message throughput: 3179388 msg/s
Server address: 127.0.0.1
Server port: 1111
Working threads: 4
Working clients: 100
Message size: 32
Errors: 0
Multicast time: 10.007 s
Total data: 3.442 GiB
Total messages: 115147638
Data throughput: 351.135 MiB/s
Message latency: 86 ns
Message throughput: 11505891 msg/s

SSL multicast server

Server address: 127.0.0.1
Server port: 2222
Working threads: 1
Working clients: 1
Message size: 32
Errors: 0
Multicast time: 10.011 s
Total data: 458.031 MiB
Total messages: 15008762
Data throughput: 45.769 MiB/s
Message latency: 667 ns
Message throughput: 1499196 msg/s
Server address: 127.0.0.1
Server port: 2222
Working threads: 4
Working clients: 100
Message size: 32
Errors: 0
Multicast time: 10.350 s
Total data: 3.082 GiB
Total messages: 103351505
Data throughput: 304.726 MiB/s
Message latency: 100 ns
Message throughput: 9984724 msg/s

UDP multicast server

Server address: 239.255.0.1
Server port: 3333
Working threads: 1
Working clients: 1
Message size: 32
Errors: 0
Multicast time: 10.004 s
Total data: 19.644 MiB
Total messages: 643205
Data throughput: 1.985 MiB/s
Message latency: 15.553 mcs
Message throughput: 64292 msg/s
Server address: 239.255.0.1
Server port: 3333
Working threads: 4
Working clients: 100
Message size: 32
Errors: 0
Multicast time: 10.007 s
Total data: 78.498 MiB
Total messages: 2571847
Data throughput: 7.862 MiB/s
Message latency: 3.891 mcs
Message throughput: 256982 msg/s

OpenSSL certificates

In order to create OpenSSL based server and client you should prepare a set of SSL certificates. Here comes several steps to get a self-signed set of SSL certificates for testing purposes:

Certificate Authority

  • Create CA private key
openssl genrsa -des3 -passout pass:qwerty -out ca-secret.key 4096
  • Remove passphrase
openssl rsa -passin pass:qwerty -in ca-secret.key -out ca.key
  • Create CA self-signed certificate
openssl req -new -x509 -days 3650 -subj '/C=BY/ST=Belarus/L=Minsk/O=Example root CA/OU=Example CA unit/CN=example.com' -key ca.key -out ca.crt -config openssl.cfg
  • Convert CA self-signed certificate to PKCS
openssl pkcs12 -clcerts -export -passout pass:qwerty -in ca.crt -inkey ca.key -out ca.p12
  • Convert CA self-signed certificate to PEM
openssl pkcs12 -clcerts -passin pass:qwerty -passout pass:qwerty -in ca.p12 -out ca.pem

SSL Server certificate

  • Create private key for the server
openssl genrsa -des3 -passout pass:qwerty -out server-secret.key 4096
  • Remove passphrase
openssl rsa -passin pass:qwerty -in server-secret.key -out server.key
  • Create CSR for the server
openssl req -new -subj '/C=BY/ST=Belarus/L=Minsk/O=Example server/OU=Example server unit/CN=server.example.com' -key server.key -out server.csr -config openssl.cfg
  • Create certificate for the server
openssl x509 -req -days 3650 -in server.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out server.crt
  • Convert the server certificate to PKCS
openssl pkcs12 -clcerts -export -passout pass:qwerty -in server.crt -inkey server.key -out server.p12
  • Convert the server certificate to PEM
openssl pkcs12 -clcerts -passin pass:qwerty -passout pass:qwerty -in server.p12 -out server.pem

SSL Client certificate

  • Create private key for the client
openssl genrsa -des3 -passout pass:qwerty -out client-secret.key 4096
  • Remove passphrase
openssl rsa -passin pass:qwerty -in client-secret.key -out client.key
  • Create CSR for the client
openssl req -new -subj '/C=BY/ST=Belarus/L=Minsk/O=Example client/OU=Example client unit/CN=client.example.com' -key client.key -out client.csr -config openssl.cfg
  • Create the client certificate
openssl x509 -req -days 3650 -in client.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out client.crt
  • Convert the client certificate to PKCS
openssl pkcs12 -clcerts -export -passout pass:qwerty -in client.crt -inkey client.key -out client.p12
  • Convert the client certificate to PEM
openssl pkcs12 -clcerts -passin pass:qwerty -passout pass:qwerty -in client.p12 -out client.pem

Diffie-Hellman key exchange

  • Create DH parameters
openssl dhparam -out dh4096.pem 4096

About

Ultra fast and low latency asynchronous socket server & client C# .NET Core library with support TCP, SSL, UDP protocols and 10K connections problem solution

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

NETCoreServer

Windows build status

Ultra fast and low latency asynchronous socket server & client C# .NET Core library with support TCP, SSL, UDP protocols and 10K connections problem solution.

NETCoreServer documentation
NETCoreServer downloads

Contents

Features

Requirements

How to build?

Setup repository

git clone https://github.com/chronoxor/NETCoreServer.git
cd NETCoreServer

Windows (Visual Studio)

Open and build NETCoreServer.sln or run the build script:

cd build
vs.bat

The build script will create "release" directory with zip files:

  • NETCoreServer.zip - C# Server assembly
  • Benchmarks.zip - C# Server benchmarks
  • Examples.zip - C# Server examples

Examples

Example: Asio timer

Here comes the example of Asio timer. It can be used to wait for some action in future with providing absolute time or relative time span. Asio timer can be used in synchronous or asynchronous modes.

usingSystem;usingSystem.Threading;usingNETCoreServer;namespaceAsioTimer{classAsioTimer:Timer{publicAsioTimer(Serviceservice):base(service){}protectedoverridevoidOnTimer(boolcanceled){Console.WriteLine("Asio timer "+(canceled?"canceled":"expired"));}protectedoverridevoidOnError(interror,stringcategory,stringmessage){Console.WriteLine($"Asio timer caught an error with code {error} and category '{category}': {message}");}}classProgram{staticvoidMain(){// Create a new servicevarservice=newService();// Start the serviceConsole.Write("Service starting...");service.Start();Console.WriteLine("Done!");// Create a new Asio timervartimer=newAsioTimer(service);// Setup and synchronously wait for the timertimer.Setup(DateTime.UtcNow.AddSeconds(1));timer.WaitSync();// Setup and asynchronously wait for the timertimer.Setup(TimeSpan.FromSeconds(1));timer.WaitAsync();// Wait for a while...Thread.Sleep(2000);// Setup and asynchronously wait for the timertimer.Setup(TimeSpan.FromSeconds(1));timer.WaitAsync();// Wait for a while...Thread.Sleep(500);// Cancel the timertimer.Cancel();// Wait for a while...Thread.Sleep(500);// Stop the serviceConsole.Write("Service stopping...");service.Stop();Console.WriteLine("Done!");}}}

Output of the above example is the following:

Service starting...Done!
Asio timer expired
Asio timer canceled
Service stopping...Done!

Example: TCP chat server

Here comes the example of the TCP chat server. It handles multiple TCP client sessions and multicast received message from any session to all ones. Also it is possible to send admin message directly from the server.

usingSystem;usingSystem.Text;usingNETCoreServer;namespaceTcpChatServer{classChatSession:TcpSession{publicChatSession(TcpServerserver):base(server){}protectedoverridevoidOnConnected(){Console.WriteLine($"Chat TCP session with Id {Id} connected!");// Send invite messagestringmessage="Hello from TCP chat! Please send a message or '!' to disconnect the client!";Send(message);}protectedoverridevoidOnDisconnected(){Console.WriteLine($"Chat TCP session with Id {Id} disconnected!");}protectedoverridevoidOnReceived(byte[]buffer){stringmessage=Encoding.UTF8.GetString(buffer);Console.WriteLine("Incoming: "+message);// Multicast message to all connected sessionsServer.Multicast(message);// If the buffer starts with '!' the disconnect the current sessionif(message=="!")Disconnect();}protectedoverridevoidOnError(interror,stringcategory,stringmessage){Console.WriteLine($"Chat TCP session caught an error with code {error} and category '{category}': {message}");}}classChatServer:TcpServer{publicChatServer(Serviceservice,InternetProtocolprotocol,intport):base(service,protocol,port){}protectedoverrideTcpSessionCreateSession(){returnnewChatSession(this);}protectedoverridevoidOnError(interror,stringcategory,stringmessage){Console.WriteLine($"Chat TCP server caught an error with code {error} and category '{category}': {message}");}}classProgram{staticvoidMain(string[]args){// TCP server portintport=1111;if(args.Length>0)port=int.Parse(args[0]);Console.WriteLine($"TCP server port: {port}");// Create a new servicevarservice=newService();// Start the serviceConsole.Write("Service starting...");service.Start();Console.WriteLine("Done!");// Create a new TCP chat servervarserver=newChatServer(service,InternetProtocol.IPv4,port);// Start the serverConsole.Write("Server starting...");server.Start();Console.WriteLine("Done!");Console.WriteLine("Press Enter to stop the server or '!' to restart the server...");// Perform text inputfor(;;){stringline=Console.ReadLine();if(line==String.Empty)break;// Restart the serverif(line=="!"){Console.Write("Server restarting...");server.Restart();Console.WriteLine("Done!");continue;}// Multicast admin message to all sessionsline="(admin) "+line;server.Multicast(line);}// Stop the serverConsole.Write("Server stopping...");server.Stop();Console.WriteLine("Done!");// Stop the serviceConsole.Write("Service stopping...");service.Stop();Console.WriteLine("Done!");}}}

Example: TCP chat client

Here comes the example of the TCP chat client. It connects to the TCP chat server and allows to send message to it and receive new messages.

usingSystem;usingSystem.Text;usingSystem.Threading;usingNETCoreServer;namespaceTcpChatClient{classChatClient:TcpClient{publicChatClient(Serviceservice,stringaddress,intport):base(service,address,port){}publicvoidDisconnectAndStop(){_stop=true;Disconnect();while(IsConnected)Thread.Yield();}protectedoverridevoidOnConnected(){Console.WriteLine($"Chat TCP client connected a new session with Id {Id}");}protectedoverridevoidOnDisconnected(){Console.WriteLine($"Chat TCP client disconnected a session with Id {Id}");// Wait for a while...Thread.Sleep(1000);// Try to connect againif(!_stop)Connect();}protectedoverridevoidOnReceived(byte[]buffer){Console.WriteLine(Encoding.UTF8.GetString(buffer));}protectedoverridevoidOnError(interror,stringcategory,stringmessage){Console.WriteLine($"Chat TCP client caught an error with code {error} and category '{category}': {message}");}privatebool_stop;}classProgram{staticvoidMain(string[]args){// TCP server addressstringaddress="127.0.0.1";if(args.Length>0)address=args[0];// TCP server portintport=1111;if(args.Length>1)port=int.Parse(args[1]);Console.WriteLine($"TCP server address: {address}");Console.WriteLine($"TCP server port: {port}");// Create a new servicevarservice=newService();// Start the serviceConsole.Write("Service starting...");service.Start();Console.WriteLine("Done!");// Create a new TCP chat clientvarclient=newChatClient(service,address,port);// Connect the clientConsole.Write("Client connecting...");client.Connect();Console.WriteLine("Done!");Console.WriteLine("Press Enter to stop the client or '!' to reconnect the client...");// Perform text inputfor(;;){stringline=Console.ReadLine();if(line==String.Empty)break;// Disconnect the clientif(line=="!"){Console.Write("Client disconnecting...");client.Disconnect();Console.WriteLine("Done!");continue;}// Send the entered text to the chat serverclient.Send(line);}// Disconnect the clientConsole.Write("Client disconnecting...");client.DisconnectAndStop();Console.WriteLine("Done!");// Stop the serviceConsole.Write("Service stopping...");service.Stop();Console.WriteLine("Done!");}}}

Example: SSL chat server

Here comes the example of the SSL chat server. It handles multiple SSL client sessions and multicast received message from any session to all ones. Also it is possible to send admin message directly from the server.

This example is very similar to the TCP one except the code that prepares SSL context and handshake handler.

usingSystem;usingSystem.Text;usingNETCoreServer;namespaceSslChatServer{classChatSession:SslSession{publicChatSession(SslServerserver):base(server){}protectedoverridevoidOnConnected(){Console.WriteLine($"Chat SSL session with Id {Id} connected!");// Send invite messagestringmessage="Hello from SSL chat! Please send a message or '!' to disconnect the client!";Send(message);}protectedoverridevoidOnDisconnected(){Console.WriteLine($"Chat SSL session with Id {Id} disconnected!");}protectedoverridevoidOnReceived(byte[]buffer){stringmessage=Encoding.UTF8.GetString(buffer);Console.WriteLine("Incoming: "+message);// Multicast message to all connected sessionsServer.Multicast(message);// If the buffer starts with '!' the disconnect the current sessionif(message=="!")Disconnect();}protectedoverridevoidOnError(interror,stringcategory,stringmessage){Console.WriteLine($"Chat SSL session caught an error with code {error} and category '{category}': {message}");}}classChatServer:SslServer{publicChatServer(Serviceservice,SslContextcontext,InternetProtocolprotocol,intport):base(service,context,protocol,port){}protectedoverrideSslSessionCreateSession(){returnnewChatSession(this);}protectedoverridevoidOnError(interror,stringcategory,stringmessage){Console.WriteLine($"Chat SSL server caught an error with code {error} and category '{category}': {message}");}}classProgram{staticvoidMain(string[]args){// SSL server portintport=2222;if(args.Length>0)port=int.Parse(args[0]);Console.WriteLine($"SSL server port: {port}");// Create a new servicevarservice=newService();// Start the serviceConsole.Write("Service starting...");service.Start();Console.WriteLine("Done!");// Create and prepare a new SSL server contextvarcontext=newSslContext(SslMethod.TLSV12);context.SetPassword("qwerty");context.UseCertificateChainFile("../../../../Tools/certificates/server.pem");context.UsePrivateKeyFile("../../../../Tools/certificates/server.pem",SslFileFormat.PEM);context.UseTmpDHFile("../../../../Tools/certificates/dh4096.pem");// Create a new SSL chat servervarserver=newChatServer(service,context,InternetProtocol.IPv4,port);// Start the serverConsole.Write("Server starting...");server.Start();Console.WriteLine("Done!");Console.WriteLine("Press Enter to stop the server or '!' to restart the server...");// Perform text inputfor(;;){stringline=Console.ReadLine();if(line==String.Empty)break;// Restart the serverif(line=="!"){Console.Write("Server restarting...");server.Restart();Console.WriteLine("Done!");continue;}// Multicast admin message to all sessionsline="(admin) "+line;server.Multicast(line);}// Stop the serverConsole.Write("Server stopping...");server.Stop();Console.WriteLine("Done!");// Stop the serviceConsole.Write("Service stopping...");service.Stop();Console.WriteLine("Done!");}}}

Example: SSL chat client

Here comes the example of the SSL chat client. It connects to the SSL chat server and allows to send message to it and receive new messages.

This example is very similar to the TCP one except the code that prepares SSL context and handshake handler.

usingSystem;usingSystem.Text;usingSystem.Threading;usingNETCoreServer;namespaceSslChatClient{classChatClient:SslClient{publicChatClient(Serviceservice,SslContextcontext,stringaddress,intport):base(service,context,address,port){}publicvoidDisconnectAndStop(){_stop=true;Disconnect();while(IsConnected)Thread.Yield();}protectedoverridevoidOnConnected(){Console.WriteLine($"Chat SSL client connected a new session with Id {Id}");}protectedoverridevoidOnDisconnected(){Console.WriteLine($"Chat SSL client disconnected a session with Id {Id}");// Wait for a while...Thread.Sleep(1000);// Try to connect againif(!_stop)Connect();}protectedoverridevoidOnReceived(byte[]buffer){Console.WriteLine(Encoding.UTF8.GetString(buffer));}protectedoverridevoidOnError(interror,stringcategory,stringmessage){Console.WriteLine($"Chat SSL client caught an error with code {error} and category '{category}': {message}");}privatebool_stop;}classProgram{staticvoidMain(string[]args){// SSL server addressstringaddress="127.0.0.1";if(args.Length>0)address=args[0];// SSL server portintport=2222;if(args.Length>1)port=int.Parse(args[1]);Console.WriteLine($"SSL server address: {address}");Console.WriteLine($"SSL server port: {port}");// Create a new servicevarservice=newService();// Start the serviceConsole.Write("Service starting...");service.Start();Console.WriteLine("Done!");// Create and prepare a new SSL client contextvarcontext=newSslContext(SslMethod.TLSV12);context.SetVerifyMode(SslVerifyMode.VerifyPeer);context.LoadVerifyFile("../../../../Tools/certificates/ca.pem");// Create a new SSL chat clientvarclient=newChatClient(service,context,address,port);// Connect the clientConsole.Write("Client connecting...");client.Connect();Console.WriteLine("Done!");Console.WriteLine("Press Enter to stop the client or '!' to reconnect the client...");// Perform text inputfor(;;){stringline=Console.ReadLine();if(line==String.Empty)break;// Disconnect the clientif(line=="!"){Console.Write("Client disconnecting...");client.Disconnect();Console.WriteLine("Done!");continue;}// Send the entered text to the chat serverclient.Send(line);}// Disconnect the clientConsole.Write("Client disconnecting...");client.DisconnectAndStop();Console.WriteLine("Done!");// Stop the serviceConsole.Write("Service stopping...");service.Stop();Console.WriteLine("Done!");}}}

Example: UDP echo server

Here comes the example of the UDP echo server. It receives a datagram mesage from any UDP client and resend it back without any changes.

usingSystem;usingSystem.Text;usingNETCoreServer;namespaceUdpEchoServer{classEchoServer:UdpServer{publicEchoServer(Serviceservice,InternetProtocolprotocol,intport):base(service,protocol,port){}protectedoverridevoidOnReceived(UdpEndpointendpoint,byte[]buffer){Console.WriteLine("Incoming: "+Encoding.UTF8.GetString(buffer));// Echo the message back to the senderSend(endpoint,buffer);}protectedoverridevoidOnError(interror,stringcategory,stringmessage){Console.WriteLine($"Echo UDP server caught an error with code {error} and category '{category}': {message}");}}classProgram{staticvoidMain(string[]args){// UDP server portintport=3333;if(args.Length>0)port=int.Parse(args[0]);Console.WriteLine($"UDP server port: {port}");// Create a new servicevarservice=newService();// Start the serviceConsole.Write("Service starting...");service.Start();Console.WriteLine("Done!");// Create a new UDP echo servervarserver=newEchoServer(service,InternetProtocol.IPv4,port);// Start the serverConsole.Write("Server starting...");server.Start();Console.WriteLine("Done!");Console.WriteLine("Press Enter to stop the server or '!' to restart the server...");// Perform text inputfor(;;){stringline=Console.ReadLine();if(line==String.Empty)break;// Restart the serverif(line=="!"){Console.Write("Server restarting...");server.Restart();Console.WriteLine("Done!");}}// Stop the serverConsole.Write("Server stopping...");server.Stop();Console.WriteLine("Done!");// Stop the serviceConsole.Write("Service stopping...");service.Stop();Console.WriteLine("Done!");}}}

Example: UDP echo client

Here comes the example of the UDP echo client. It sends user datagram message to UDP server and listen for response.

usingSystem;usingSystem.Text;usingSystem.Threading;usingNETCoreServer;namespaceUdpEchoClient{classEchoClient:UdpClient{publicEchoClient(Serviceservice,stringaddress,intport):base(service,address,port){}publicvoidDisconnectAndStop(){_stop=true;Disconnect();while(IsConnected)Thread.Yield();}protectedoverridevoidOnConnected(){Console.WriteLine($"Echo UDP client connected a new session with Id {Id}");}protectedoverridevoidOnDisconnected(){Console.WriteLine($"Echo UDP client disconnected a session with Id {Id}");// Wait for a while...Thread.Sleep(1000);// Try to connect againif(!_stop)Connect();}protectedoverridevoidOnReceived(UdpEndpointendpoint,byte[]buffer){Console.WriteLine("Incoming: "+Encoding.UTF8.GetString(buffer));}protectedoverridevoidOnError(interror,stringcategory,stringmessage){Console.WriteLine($"Echo UDP client caught an error with code {error} and category '{category}': {message}");}privatebool_stop;}classProgram{staticvoidMain(string[]args){// UDP server addressstringaddress="127.0.0.1";if(args.Length>0)address=args[0];// UDP server portintport=3333;if(args.Length>1)port=int.Parse(args[1]);Console.WriteLine($"UDP server address: {address}");Console.WriteLine($"UDP server port: {port}");// Create a new servicevarservice=newService();// Start the serviceConsole.Write("Service starting...");service.Start();Console.WriteLine("Done!");// Create a new TCP chat clientvarclient=newEchoClient(service,address,port);// Connect the clientConsole.Write("Client connecting...");client.Connect();Console.WriteLine("Done!");Console.WriteLine("Press Enter to stop the client or '!' to reconnect the client...");// Perform text inputfor(;;){stringline=Console.ReadLine();if(line==String.Empty)break;// Disconnect the clientif(line=="!"){Console.Write("Client disconnecting...");client.Disconnect();Console.WriteLine("Done!");continue;}// Send the entered text to the chat serverclient.Send(line);}// Disconnect the clientConsole.Write("Client disconnecting...");client.DisconnectAndStop();Console.WriteLine("Done!");// Stop the serviceConsole.Write("Service stopping...");service.Stop();Console.WriteLine("Done!");}}}

Example: UDP multicast server

Here comes the example of the UDP multicast server. It use multicast IP address to multicast datagram messages to all client that joined corresponding UDP multicast group.

usingSystem;usingSystem.Text;usingNETCoreServer;namespaceUdpMulticastServer{classMulticastServer:UdpServer{publicMulticastServer(Serviceservice,InternetProtocolprotocol,intport):base(service,protocol,port){}protectedoverridevoidOnError(interror,stringcategory,stringmessage){Console.WriteLine($"Multicast UDP server caught an error with code {error} and category '{category}': {message}");}}classProgram{staticvoidMain(string[]args){// UDP multicast addressstringmulticastAddress="239.255.0.1";if(args.Length>0)multicastAddress=args[0];// UDP multicast portintmulticastPort=3334;if(args.Length>1)multicastPort=int.Parse(args[1]);Console.WriteLine($"UDP multicast address: {multicastAddress}");Console.WriteLine($"UDP multicast port: {multicastPort}");// Create a new servicevarservice=newService();// Start the serviceConsole.Write("Service starting...");service.Start();Console.WriteLine("Done!");// Create a new UDP multicast servervarserver=newMulticastServer(service,InternetProtocol.IPv4,0);// Start the multicast serverConsole.Write("Server starting...");server.Start(multicastAddress,multicastPort);Console.WriteLine("Done!");Console.WriteLine("Press Enter to stop the server or '!' to restart the server...");// Perform text inputfor(;;){stringline=Console.ReadLine();if(line==String.Empty)break;// Restart the serverif(line=="!"){Console.Write("Server restarting...");server.Restart();Console.WriteLine("Done!");continue;}// Multicast admin message to all sessionsline="(admin) "+line;server.Multicast(line);}// Stop the serverConsole.Write("Server stopping...");server.Stop();Console.WriteLine("Done!");// Stop the serviceConsole.Write("Service stopping...");service.Stop();Console.WriteLine("Done!");}}}

Example: UDP multicast client

Here comes the example of the UDP multicast client. It use multicast IP address and joins UDP multicast group in order to receive multicasted datagram messages from UDP server.

usingSystem;usingSystem.Text;usingSystem.Threading;usingNETCoreServer;namespaceUdpMulticastClient{classMulticastClient:UdpClient{publicstringMulticast;publicMulticastClient(Serviceservice,stringaddress,intport):base(service,address,port){}publicvoidDisconnectAndStop(){_stop=true;Disconnect();while(IsConnected)Thread.Yield();}protectedoverridevoidOnConnected(){Console.WriteLine($"Multicast UDP client connected a new session with Id {Id}");// Join UDP multicast groupJoinMulticastGroup(Multicast);}protectedoverridevoidOnDisconnected(){Console.WriteLine($"Multicast UDP client disconnected a session with Id {Id}");// Wait for a while...Thread.Sleep(1000);// Try to connect againif(!_stop)Connect();}protectedoverridevoidOnReceived(UdpEndpointendpoint,byte[]buffer){Console.WriteLine("Incoming: "+Encoding.UTF8.GetString(buffer));}protectedoverridevoidOnError(interror,stringcategory,stringmessage){Console.WriteLine($"Multicast UDP client caught an error with code {error} and category '{category}': {message}");}privatebool_stop;}classProgram{staticvoidMain(string[]args){// UDP listen addressstringlistenAddress="0.0.0.0";if(args.Length>0)listenAddress=args[0];// UDP multicast addressstringmulticastAddress="239.255.0.1";if(args.Length>1)multicastAddress=args[1];// UDP multicast portintmulticastPort=3334;if(args.Length>2)multicastPort=int.Parse(args[2]);Console.WriteLine($"UDP listen address: {listenAddress}");Console.WriteLine($"UDP multicast address: {multicastAddress}");Console.WriteLine($"UDP multicast port: {multicastPort}");// Create a new servicevarservice=newService();// Start the serviceConsole.Write("Service starting...");service.Start();Console.WriteLine("Done!");// Create a new TCP chat clientvarclient=newMulticastClient(service,listenAddress,multicastPort);client.SetupMulticast(true);client.Multicast=multicastAddress;// Connect the clientConsole.Write("Client connecting...");client.Connect();Console.WriteLine("Done!");Console.WriteLine("Press Enter to stop the client or '!' to reconnect the client...");// Perform text inputfor(;;){stringline=Console.ReadLine();if(line==String.Empty)break;// Disconnect the clientif(line=="!"){Console.Write("Client disconnecting...");client.Disconnect();Console.WriteLine("Done!");continue;}// Send the entered text to the chat serverclient.Send(line);}// Disconnect the clientConsole.Write("Client disconnecting...");client.DisconnectAndStop();Console.WriteLine("Done!");// Stop the serviceConsole.Write("Service stopping...");service.Stop();Console.WriteLine("Done!");}}}

Performance

Here comes several communication scenarios with timing measurements.

Benchmark environment is the following:

CPU architecutre: Intel(R) Core(TM) i7-4790K CPU @ 4.00GHz
CPU logical cores: 8
CPU physical cores: 4
CPU clock speed: 3.998 GHz
CPU Hyper-Threading: enabled
RAM total: 31.962 GiB
RAM free: 21.623 GiB
OS version: Microsoft Windows 8 Enterprise Edition (build 9200), 64-bit
OS bits: 64-bit
Process bits: 64-bit
Process configuaraion: release

Benchmark: Round-Trip

Round-trip

This scenario sends lots of messages from several clients to a server. The server responses to each message and resend the similar response to the client. The benchmark measures total Round-trip time to send all messages and receive all responses, messages & data throughput, count of errors.

TCP echo server

Server address: 127.0.0.1
Server port: 1111
Working threads: 1
Working clients: 1
Messages to send: 1000000
Message size: 32
Errors: 0
Round-trip time: 3.893 s
Total data: 30.530 MiB
Total messages: 1000000
Data throughput: 7.858 MiB/s
Message latency: 3.893 mcs
Message throughput: 256842 msg/s
Server address: 127.0.0.1
Server port: 1111
Working threads: 4
Working clients: 100
Messages to send: 1000000
Message size: 32
Errors: 0
Round-trip time: 1.557 s
Total data: 30.518 MiB
Total messages: 999632
Data throughput: 19.597 MiB/s
Message latency: 1.558 mcs
Message throughput: 641705 msg/s

SSL echo server

Server address: 127.0.0.1
Server port: 2222
Working threads: 1
Working clients: 1
Messages to send: 1000000
Message size: 32
Errors: 0
Round-trip time: 7.201 s
Total data: 30.530 MiB
Total messages: 1000000
Data throughput: 4.243 MiB/s
Message latency: 7.201 mcs
Message throughput: 138858 msg/s
Server address: 127.0.0.1
Server port: 2222
Working threads: 4
Working clients: 100
Messages to send: 1000000
Message size: 32
Errors: 0
Round-trip time: 4.365 s
Total data: 30.328 MiB
Total messages: 993547
Data throughput: 6.968 MiB/s
Message latency: 4.393 mcs
Message throughput: 227600 msg/s

UDP echo server

Server address: 127.0.0.1
Server port: 3333
Working threads: 1
Working clients: 1
Messages to send: 1000000
Message size: 32
Errors: 0
Round-trip time: 22.071 s
Total data: 30.530 MiB
Total messages: 1000000
Data throughput: 1.391 MiB/s
Message latency: 22.071 mcs
Message throughput: 45306 msg/s
Server address: 127.0.0.1
Server port: 3333
Working threads: 4
Working clients: 100
Messages to send: 1000000
Message size: 32
Errors: 0
Round-trip time: 6.086 s
Total data: 30.512 MiB
Total messages: 999471
Data throughput: 5.011 MiB/s
Message latency: 6.090 mcs
Message throughput: 164201 msg/s

Benchmark: Multicast

Multicast

In this scenario server multicasts messages to all connected clients. The benchmark counts total messages received by all clients for all the working time and measures messages & data throughput, count of errors.

TCP multicast server

Server address: 127.0.0.1
Server port: 1111
Working threads: 1
Working clients: 1
Message size: 32
Errors: 0
Multicast time: 10.002 s
Total data: 970.554 MiB
Total messages: 31802690
Data throughput: 97.027 MiB/s
Message latency: 314 ns
Message throughput: 3179388 msg/s
Server address: 127.0.0.1
Server port: 1111
Working threads: 4
Working clients: 100
Message size: 32
Errors: 0
Multicast time: 10.007 s
Total data: 3.442 GiB
Total messages: 115147638
Data throughput: 351.135 MiB/s
Message latency: 86 ns
Message throughput: 11505891 msg/s

SSL multicast server

Server address: 127.0.0.1
Server port: 2222
Working threads: 1
Working clients: 1
Message size: 32
Errors: 0
Multicast time: 10.011 s
Total data: 458.031 MiB
Total messages: 15008762
Data throughput: 45.769 MiB/s
Message latency: 667 ns
Message throughput: 1499196 msg/s
Server address: 127.0.0.1
Server port: 2222
Working threads: 4
Working clients: 100
Message size: 32
Errors: 0
Multicast time: 10.350 s
Total data: 3.082 GiB
Total messages: 103351505
Data throughput: 304.726 MiB/s
Message latency: 100 ns
Message throughput: 9984724 msg/s

UDP multicast server

Server address: 239.255.0.1
Server port: 3333
Working threads: 1
Working clients: 1
Message size: 32
Errors: 0
Multicast time: 10.004 s
Total data: 19.644 MiB
Total messages: 643205
Data throughput: 1.985 MiB/s
Message latency: 15.553 mcs
Message throughput: 64292 msg/s
Server address: 239.255.0.1
Server port: 3333
Working threads: 4
Working clients: 100
Message size: 32
Errors: 0
Multicast time: 10.007 s
Total data: 78.498 MiB
Total messages: 2571847
Data throughput: 7.862 MiB/s
Message latency: 3.891 mcs
Message throughput: 256982 msg/s

OpenSSL certificates

In order to create OpenSSL based server and client you should prepare a set of SSL certificates. Here comes several steps to get a self-signed set of SSL certificates for testing purposes:

Certificate Authority

  • Create CA private key
openssl genrsa -des3 -passout pass:qwerty -out ca-secret.key 4096
  • Remove passphrase
openssl rsa -passin pass:qwerty -in ca-secret.key -out ca.key
  • Create CA self-signed certificate
openssl req -new -x509 -days 3650 -subj '/C=BY/ST=Belarus/L=Minsk/O=Example root CA/OU=Example CA unit/CN=example.com' -key ca.key -out ca.crt -config openssl.cfg
  • Convert CA self-signed certificate to PKCS
openssl pkcs12 -clcerts -export -passout pass:qwerty -in ca.crt -inkey ca.key -out ca.p12
  • Convert CA self-signed certificate to PEM
openssl pkcs12 -clcerts -passin pass:qwerty -passout pass:qwerty -in ca.p12 -out ca.pem

SSL Server certificate

  • Create private key for the server
openssl genrsa -des3 -passout pass:qwerty -out server-secret.key 4096
  • Remove passphrase
openssl rsa -passin pass:qwerty -in server-secret.key -out server.key
  • Create CSR for the server
openssl req -new -subj '/C=BY/ST=Belarus/L=Minsk/O=Example server/OU=Example server unit/CN=server.example.com' -key server.key -out server.csr -config openssl.cfg
  • Create certificate for the server
openssl x509 -req -days 3650 -in server.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out server.crt
  • Convert the server certificate to PKCS
openssl pkcs12 -clcerts -export -passout pass:qwerty -in server.crt -inkey server.key -out server.p12
  • Convert the server certificate to PEM
openssl pkcs12 -clcerts -passin pass:qwerty -passout pass:qwerty -in server.p12 -out server.pem

SSL Client certificate

  • Create private key for the client
openssl genrsa -des3 -passout pass:qwerty -out client-secret.key 4096
  • Remove passphrase
openssl rsa -passin pass:qwerty -in client-secret.key -out client.key
  • Create CSR for the client
openssl req -new -subj '/C=BY/ST=Belarus/L=Minsk/O=Example client/OU=Example client unit/CN=client.example.com' -key client.key -out client.csr -config openssl.cfg
  • Create the client certificate
openssl x509 -req -days 3650 -in client.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out client.crt
  • Convert the client certificate to PKCS
openssl pkcs12 -clcerts -export -passout pass:qwerty -in client.crt -inkey client.key -out client.p12
  • Convert the client certificate to PEM
openssl pkcs12 -clcerts -passin pass:qwerty -passout pass:qwerty -in client.p12 -out client.pem

Diffie-Hellman key exchange

  • Create DH parameters
openssl dhparam -out dh4096.pem 4096

About

Ultra fast and low latency asynchronous socket server & client C# .NET Core library with support TCP, SSL, UDP protocols and 10K connections problem solution

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors