Skip to content

Repository files navigation

NetCoreServer

Awesome .NETLinux build statusOSX build statusWindows build statusNuGet

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

NetCoreServer documentation
NetCoreServer downloads

Contents

Features

Requirements

Optional:

How to build?

Setup repository

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

Linux

cd build
./unix.sh

OSX

cd build
./unix.sh

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: 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.Net;usingSystem.Net.Sockets;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!";SendAsync(message);}protectedoverridevoidOnDisconnected(){Console.WriteLine($"Chat TCP session with Id {Id} disconnected!");}protectedoverridevoidOnReceived(byte[]buffer,longoffset,longsize){stringmessage=Encoding.UTF8.GetString(buffer,(int)offset,(int)size);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(SocketErrorerror){Console.WriteLine($"Chat TCP session caught an error with code {error}");}}classChatServer:TcpServer{publicChatServer(IPAddressaddress,intport):base(address,port){}protectedoverrideTcpSessionCreateSession(){returnnewChatSession(this);}protectedoverridevoidOnError(SocketErrorerror){Console.WriteLine($"Chat TCP server caught an error with code {error}");}}classProgram{staticvoidMain(string[]args){// TCP server portintport=1111;if(args.Length>0)port=int.Parse(args[0]);Console.WriteLine($"TCP server port: {port}");Console.WriteLine();// Create a new TCP chat servervarserver=newChatServer(IPAddress.Any,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(string.IsNullOrEmpty(line))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!");}}}

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.Net.Sockets;usingSystem.Text;usingSystem.Threading;usingTcpClient=NetCoreServer.TcpClient;namespaceTcpChatClient{classChatClient:TcpClient{publicChatClient(stringaddress,intport):base(address,port){}publicvoidDisconnectAndStop(){_stop=true;DisconnectAsync();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)ConnectAsync();}protectedoverridevoidOnReceived(byte[]buffer,longoffset,longsize){Console.WriteLine(Encoding.UTF8.GetString(buffer,(int)offset,(int)size));}protectedoverridevoidOnError(SocketErrorerror){Console.WriteLine($"Chat TCP client caught an error with code {error}");}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}");Console.WriteLine();// Create a new TCP chat clientvarclient=newChatClient(address,port);// Connect the clientConsole.Write("Client connecting...");client.ConnectAsync();Console.WriteLine("Done!");Console.WriteLine("Press Enter to stop the client or '!' to reconnect the client...");// Perform text inputfor(;;){stringline=Console.ReadLine();if(string.IsNullOrEmpty(line))break;// Disconnect the clientif(line=="!"){Console.Write("Client disconnecting...");client.DisconnectAsync();Console.WriteLine("Done!");continue;}// Send the entered text to the chat serverclient.SendAsync(line);}// Disconnect the clientConsole.Write("Client disconnecting...");client.DisconnectAndStop();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.Net;usingSystem.Net.Sockets;usingSystem.Security.Authentication;usingSystem.Security.Cryptography.X509Certificates;usingSystem.Text;usingNetCoreServer;namespaceSslChatServer{classChatSession:SslSession{publicChatSession(SslServerserver):base(server){}protectedoverridevoidOnConnected(){Console.WriteLine($"Chat SSL session with Id {Id} connected!");}protectedoverridevoidOnHandshaked(){Console.WriteLine($"Chat SSL session with Id {Id} handshaked!");// 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,longoffset,longsize){stringmessage=Encoding.UTF8.GetString(buffer,(int)offset,(int)size);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(SocketErrorerror){Console.WriteLine($"Chat SSL session caught an error with code {error}");}}classChatServer:SslServer{publicChatServer(SslContextcontext,IPAddressaddress,intport):base(context,address,port){}protectedoverrideSslSessionCreateSession(){returnnewChatSession(this);}protectedoverridevoidOnError(SocketErrorerror){Console.WriteLine($"Chat SSL server caught an error with code {error}");}}classProgram{staticvoidMain(string[]args){// SSL server portintport=2222;if(args.Length>0)port=int.Parse(args[0]);Console.WriteLine($"SSL server port: {port}");Console.WriteLine();// Create and prepare a new SSL server contextvarcontext=newSslContext(SslProtocols.Tls12,newX509Certificate2("server.pfx","qwerty"));// Create a new SSL chat servervarserver=newChatServer(context,IPAddress.Any,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(string.IsNullOrEmpty(line))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!");}}}

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.Net.Sockets;usingSystem.Security.Authentication;usingSystem.Security.Cryptography.X509Certificates;usingSystem.Text;usingSystem.Threading;usingNetCoreServer;namespaceSslChatClient{classChatClient:SslClient{publicChatClient(SslContextcontext,stringaddress,intport):base(context,address,port){}publicvoidDisconnectAndStop(){_stop=true;DisconnectAsync();while(IsConnected)Thread.Yield();}protectedoverridevoidOnConnected(){Console.WriteLine($"Chat SSL client connected a new session with Id {Id}");}protectedoverridevoidOnHandshaked(){Console.WriteLine($"Chat SSL client handshaked 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)ConnectAsync();}protectedoverridevoidOnReceived(byte[]buffer,longoffset,longsize){Console.WriteLine(Encoding.UTF8.GetString(buffer,(int)offset,(int)size));}protectedoverridevoidOnError(SocketErrorerror){Console.WriteLine($"Chat SSL client caught an error with code {error}");}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}");Console.WriteLine();// Create and prepare a new SSL client contextvarcontext=newSslContext(SslProtocols.Tls12,newX509Certificate2("client.pfx","qwerty"),(sender,certificate,chain,sslPolicyErrors)=>true);// Create a new SSL chat clientvarclient=newChatClient(context,address,port);// Connect the clientConsole.Write("Client connecting...");client.ConnectAsync();Console.WriteLine("Done!");Console.WriteLine("Press Enter to stop the client or '!' to reconnect the client...");// Perform text inputfor(;;){stringline=Console.ReadLine();if(string.IsNullOrEmpty(line))break;// Disconnect the clientif(line=="!"){Console.Write("Client disconnecting...");client.DisconnectAsync();Console.WriteLine("Done!");continue;}// Send the entered text to the chat serverclient.SendAsync(line);}// Disconnect the clientConsole.Write("Client disconnecting...");client.DisconnectAndStop();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.Net;usingSystem.Net.Sockets;usingSystem.Text;usingNetCoreServer;namespaceUdpEchoServer{classEchoServer:UdpServer{publicEchoServer(IPAddressaddress,intport):base(address,port){}protectedoverridevoidOnStarted(){// Start receive datagramsReceiveAsync();}protectedoverridevoidOnReceived(EndPointendpoint,byte[]buffer,longoffset,longsize){Console.WriteLine("Incoming: "+Encoding.UTF8.GetString(buffer,(int)offset,(int)size));// Echo the message back to the senderSendAsync(endpoint,buffer,0,size);}protectedoverridevoidOnSent(EndPointendpoint,longsent){// Continue receive datagramsReceiveAsync();}protectedoverridevoidOnError(SocketErrorerror){Console.WriteLine($"Echo UDP server caught an error with code {error}");}}classProgram{staticvoidMain(string[]args){// UDP server portintport=3333;if(args.Length>0)port=int.Parse(args[0]);Console.WriteLine($"UDP server port: {port}");Console.WriteLine();// Create a new UDP echo servervarserver=newEchoServer(IPAddress.Any,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(string.IsNullOrEmpty(line))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!");}}}

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.Net;usingSystem.Net.Sockets;usingSystem.Text;usingSystem.Threading;usingUdpClient=NetCoreServer.UdpClient;namespaceUdpEchoClient{classEchoClient:UdpClient{publicEchoClient(stringaddress,intport):base(address,port){}publicvoidDisconnectAndStop(){_stop=true;Disconnect();while(IsConnected)Thread.Yield();}protectedoverridevoidOnConnected(){Console.WriteLine($"Echo UDP client connected a new session with Id {Id}");// Start receive datagramsReceiveAsync();}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(EndPointendpoint,byte[]buffer,longoffset,longsize){Console.WriteLine("Incoming: "+Encoding.UTF8.GetString(buffer,(int)offset,(int)size));// Continue receive datagramsReceiveAsync();}protectedoverridevoidOnError(SocketErrorerror){Console.WriteLine($"Echo UDP client caught an error with code {error}");}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}");Console.WriteLine();// Create a new TCP chat clientvarclient=newEchoClient(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(string.IsNullOrEmpty(line))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!");}}}

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.Net;usingSystem.Net.Sockets;usingNetCoreServer;namespaceUdpMulticastServer{classMulticastServer:UdpServer{publicMulticastServer(IPAddressaddress,intport):base(address,port){}protectedoverridevoidOnError(SocketErrorerror){Console.WriteLine($"Multicast UDP server caught an error with code {error}");}}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}");Console.WriteLine();// Create a new UDP multicast servervarserver=newMulticastServer(IPAddress.Any,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(string.IsNullOrEmpty(line))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!");}}}

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.Net;usingSystem.Net.Sockets;usingSystem.Text;usingSystem.Threading;usingUdpClient=NetCoreServer.UdpClient;namespaceUdpMulticastClient{classMulticastClient:UdpClient{publicstringMulticast;publicMulticastClient(stringaddress,intport):base(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);// Start receive datagramsReceiveAsync();}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(EndPointendpoint,byte[]buffer,longoffset,longsize){Console.WriteLine("Incoming: "+Encoding.UTF8.GetString(buffer,(int)offset,(int)size));// Continue receive datagramsReceiveAsync();}protectedoverridevoidOnError(SocketErrorerror){Console.WriteLine($"Multicast UDP client caught an error with code {error}");}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}");Console.WriteLine();// Create a new TCP chat clientvarclient=newMulticastClient(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(string.IsNullOrEmpty(line))break;// Disconnect the clientif(line=="!"){Console.Write("Client disconnecting...");client.Disconnect();Console.WriteLine("Done!");continue;}}// Disconnect the clientConsole.Write("Client disconnecting...");client.DisconnectAndStop();Console.WriteLine("Done!");}}}

Example: HTTP server

Here comes the example of the HTTP cache server. It allows to manipulate cache data with HTTP methods (GET, POST, PUT and DELETE).

Use the following link to open Swagger OpenAPI iterative documentation: http://localhost:8080/api/index.html

OpenAPI-HTTP

usingSystem;usingSystem.Collections.Concurrent;usingSystem.Net;usingSystem.Net.Sockets;usingSystem.Text;usingNetCoreServer;namespaceHttpServer{classCommonCache{publicstaticCommonCacheGetInstance(){if(_instance==null)_instance=newCommonCache();return_instance;}publicstringGetAllCache(){varresult=newStringBuilder();result.Append("[\n");foreach(varitemin_cache){result.Append(" {\n");result.AppendFormat($" \"key\": \"{item.Key}\",\n");result.AppendFormat($" \"value\": \"{item.Value}\",\n");result.Append(" },\n");}result.Append("]\n");returnresult.ToString();}publicboolGetCacheValue(stringkey,outstringvalue){return_cache.TryGetValue(key,outvalue);}publicvoidPutCacheValue(stringkey,stringvalue){_cache[key]=value;}publicboolDeleteCacheValue(stringkey,outstringvalue){return_cache.TryRemove(key,outvalue);}privatereadonlyConcurrentDictionary<string,string>_cache=newConcurrentDictionary<string,string>();privatestaticCommonCache_instance;}classHttpCacheSession:HttpSession{publicHttpCacheSession(NetCoreServer.HttpServerserver):base(server){}protectedoverridevoidOnReceivedRequest(HttpRequestrequest){// Show HTTP request contentConsole.WriteLine(request);// Process HTTP request methodsif(request.Method=="HEAD")SendResponseAsync(Response.MakeHeadResponse());elseif(request.Method=="GET"){stringkey=request.Url;// Decode the key valuekey=Uri.UnescapeDataString(key);key=key.Replace("/api/cache","",StringComparison.InvariantCultureIgnoreCase);key=key.Replace("?key=","",StringComparison.InvariantCultureIgnoreCase);if(string.IsNullOrEmpty(key)){// Response with all cache valuesSendResponseAsync(Response.MakeGetResponse(CommonCache.GetInstance().GetAllCache(),"application/json; charset=UTF-8"));}// Get the cache value by the given keyelseif(CommonCache.GetInstance().GetCacheValue(key,outvarvalue)){// Response with the cache valueSendResponseAsync(Response.MakeGetResponse(value));}elseSendResponseAsync(Response.MakeErrorResponse("Required cache value was not found for the key: "+key,404));}elseif((request.Method=="POST")||(request.Method=="PUT")){stringkey=request.Url;stringvalue=request.Body;// Decode the key valuekey=Uri.UnescapeDataString(key);key=key.Replace("/api/cache","",StringComparison.InvariantCultureIgnoreCase);key=key.Replace("?key=","",StringComparison.InvariantCultureIgnoreCase);// Put the cache valueCommonCache.GetInstance().PutCacheValue(key,value);// Response with the cache valueSendResponseAsync(Response.MakeOkResponse());}elseif(request.Method=="DELETE"){stringkey=request.Url;// Decode the key valuekey=Uri.UnescapeDataString(key);key=key.Replace("/api/cache","",StringComparison.InvariantCultureIgnoreCase);key=key.Replace("?key=","",StringComparison.InvariantCultureIgnoreCase);// Delete the cache valueif(CommonCache.GetInstance().DeleteCacheValue(key,outvarvalue)){// Response with the cache valueSendResponseAsync(Response.MakeGetResponse(value));}elseSendResponseAsync(Response.MakeErrorResponse("Deleted cache value was not found for the key: "+key,404));}elseif(request.Method=="OPTIONS")SendResponseAsync(Response.MakeOptionsResponse());elseif(request.Method=="TRACE")SendResponseAsync(Response.MakeTraceResponse(request.Cache.Data));elseSendResponseAsync(Response.MakeErrorResponse("Unsupported HTTP method: "+request.Method));}protectedoverridevoidOnReceivedRequestError(HttpRequestrequest,stringerror){Console.WriteLine($"Request error: {error}");}protectedoverridevoidOnError(SocketErrorerror){Console.WriteLine($"HTTP session caught an error: {error}");}}classHttpCacheServer:NetCoreServer.HttpServer{publicHttpCacheServer(IPAddressaddress,intport):base(address,port){}protectedoverrideTcpSessionCreateSession(){returnnewHttpCacheSession(this);}protectedoverridevoidOnError(SocketErrorerror){Console.WriteLine($"HTTP session caught an error: {error}");}}classProgram{staticvoidMain(string[]args){// HTTP server portintport=8080;if(args.Length>0)port=int.Parse(args[0]);// HTTP server content pathstringwww="../../../../../www/api";if(args.Length>1)www=args[1];Console.WriteLine($"HTTP server port: {port}");Console.WriteLine($"HTTP server static content path: {www}");Console.WriteLine($"HTTP server website: http://localhost:{port}/api/index.html");Console.WriteLine();// Create a new HTTP servervarserver=newHttpCacheServer(IPAddress.Any,port);server.AddStaticContent(www,"/api");// 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(string.IsNullOrEmpty(line))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!");}}}

Example: HTTP client

Here comes the example of the HTTP client. It allows to send HTTP requests (GET, POST, PUT and DELETE) and receive HTTP responses.

usingSystem;usingNetCoreServer;namespaceHttpClient{classProgram{staticvoidMain(string[]args){// HTTP server addressstringaddress="127.0.0.1";if(args.Length>0)address=args[0];// HTTP server portintport=8080;if(args.Length>1)port=int.Parse(args[1]);Console.WriteLine($"HTTP server address: {address}");Console.WriteLine($"HTTP server port: {port}");Console.WriteLine();// Create a new HTTP clientvarclient=newHttpClientEx(address,port);Console.WriteLine("Press Enter to stop the client or '!' to reconnect the client...");// Perform text inputfor(;;){stringline=Console.ReadLine();if(string.IsNullOrEmpty(line))break;// Reconnect the clientif(line=="!"){Console.Write("Client reconnecting...");if(client.IsConnected)client.ReconnectAsync();elseclient.ConnectAsync();Console.WriteLine("Done!");continue;}varcommands=line.Split(' ');if(commands.Length<2){Console.WriteLine("HTTP method and URL must be entered!");continue;}if(commands[0].ToUpper()=="HEAD"){varresponse=client.SendHeadRequest(commands[1]).Result;Console.WriteLine(response);}elseif(commands[0].ToUpper()=="GET"){varresponse=client.SendGetRequest(commands[1]).Result;Console.WriteLine(response);}elseif(commands[0].ToUpper()=="POST"){if(commands.Length<3){Console.WriteLine("HTTP method, URL and body must be entered!");continue;}varresponse=client.SendPostRequest(commands[1],commands[2]).Result;Console.WriteLine(response);}elseif(commands[0].ToUpper()=="PUT"){if(commands.Length<3){Console.WriteLine("HTTP method, URL and body must be entered!");continue;}varresponse=client.SendPutRequest(commands[1],commands[2]).Result;Console.WriteLine(response);}elseif(commands[0].ToUpper()=="DELETE"){varresponse=client.SendDeleteRequest(commands[1]).Result;Console.WriteLine(response);}elseif(commands[0].ToUpper()=="OPTIONS"){varresponse=client.SendOptionsRequest(commands[1]).Result;Console.WriteLine(response);}elseif(commands[0].ToUpper()=="TRACE"){varresponse=client.SendTraceRequest(commands[1]).Result;Console.WriteLine(response);}elseConsole.WriteLine("Unknown HTTP method");}// Disconnect the clientConsole.Write("Client disconnecting...");client.Disconnect();Console.WriteLine("Done!");}}}

Example: HTTPS server

Here comes the example of the HTTPS cache server. It allows to manipulate cache data with HTTP methods (GET, POST, PUT and DELETE) with secured transport protocol.

Use the following link to open Swagger OpenAPI iterative documentation: https://localhost:8443/api/index.html

OpenAPI-HTTPS

usingSystem;usingSystem.Collections.Concurrent;usingSystem.Net;usingSystem.Net.Sockets;usingSystem.Security.Authentication;usingSystem.Security.Cryptography.X509Certificates;usingSystem.Text;usingNetCoreServer;namespaceHttpsServer{classCommonCache{publicstaticCommonCacheGetInstance(){if(_instance==null)_instance=newCommonCache();return_instance;}publicstringGetAllCache(){varresult=newStringBuilder();result.Append("[\n");foreach(varitemin_cache){result.Append(" {\n");result.AppendFormat($" \"key\": \"{item.Key}\",\n");result.AppendFormat($" \"value\": \"{item.Value}\",\n");result.Append(" },\n");}result.Append("]\n");returnresult.ToString();}publicboolGetCacheValue(stringkey,outstringvalue){return_cache.TryGetValue(key,outvalue);}publicvoidPutCacheValue(stringkey,stringvalue){_cache[key]=value;}publicboolDeleteCacheValue(stringkey,outstringvalue){return_cache.TryRemove(key,outvalue);}privatereadonlyConcurrentDictionary<string,string>_cache=newConcurrentDictionary<string,string>();privatestaticCommonCache_instance;}classHttpsCacheSession:HttpsSession{publicHttpsCacheSession(NetCoreServer.HttpsServerserver):base(server){}protectedoverridevoidOnReceivedRequest(HttpRequestrequest){// Show HTTP request contentConsole.WriteLine(request);// Process HTTP request methodsif(request.Method=="HEAD")SendResponseAsync(Response.MakeHeadResponse());elseif(request.Method=="GET"){stringkey=request.Url;// Decode the key valuekey=Uri.UnescapeDataString(key);key=key.Replace("/api/cache","",StringComparison.InvariantCultureIgnoreCase);key=key.Replace("?key=","",StringComparison.InvariantCultureIgnoreCase);if(string.IsNullOrEmpty(key)){// Response with all cache valuesSendResponseAsync(Response.MakeGetResponse(CommonCache.GetInstance().GetAllCache(),"application/json; charset=UTF-8"));}// Get the cache value by the given keyelseif(CommonCache.GetInstance().GetCacheValue(key,outvarvalue)){// Response with the cache valueSendResponseAsync(Response.MakeGetResponse(value));}elseSendResponseAsync(Response.MakeErrorResponse("Required cache value was not found for the key: "+key,404));}elseif((request.Method=="POST")||(request.Method=="PUT")){stringkey=request.Url;stringvalue=request.Body;// Decode the key valuekey=Uri.UnescapeDataString(key);key=key.Replace("/api/cache","",StringComparison.InvariantCultureIgnoreCase);key=key.Replace("?key=","",StringComparison.InvariantCultureIgnoreCase);// Put the cache valueCommonCache.GetInstance().PutCacheValue(key,value);// Response with the cache valueSendResponseAsync(Response.MakeOkResponse());}elseif(request.Method=="DELETE"){stringkey=request.Url;// Decode the key valuekey=Uri.UnescapeDataString(key);key=key.Replace("/api/cache","",StringComparison.InvariantCultureIgnoreCase);key=key.Replace("?key=","",StringComparison.InvariantCultureIgnoreCase);// Delete the cache valueif(CommonCache.GetInstance().DeleteCacheValue(key,outvarvalue)){// Response with the cache valueSendResponseAsync(Response.MakeGetResponse(value));}elseSendResponseAsync(Response.MakeErrorResponse("Deleted cache value was not found for the key: "+key,404));}elseif(request.Method=="OPTIONS")SendResponseAsync(Response.MakeOptionsResponse());elseif(request.Method=="TRACE")SendResponseAsync(Response.MakeTraceResponse(request.Cache));elseSendResponseAsync(Response.MakeErrorResponse("Unsupported HTTP method: "+request.Method));}protectedoverridevoidOnReceivedRequestError(HttpRequestrequest,stringerror){Console.WriteLine($"Request error: {error}");}protectedoverridevoidOnError(SocketErrorerror){Console.WriteLine($"HTTPS session caught an error: {error}");}}classHttpsCacheServer:NetCoreServer.HttpsServer{publicHttpsCacheServer(SslContextcontext,IPAddressaddress,intport):base(context,address,port){}protectedoverrideSslSessionCreateSession(){returnnewHttpsCacheSession(this);}protectedoverridevoidOnError(SocketErrorerror){Console.WriteLine($"HTTPS server caught an error: {error}");}}classProgram{staticvoidMain(string[]args){// HTTPS server portintport=8443;if(args.Length>0)port=int.Parse(args[0]);// HTTPS server content pathstringwww="../../../../../www/api";if(args.Length>1)www=args[1];Console.WriteLine($"HTTPS server port: {port}");Console.WriteLine($"HTTPS server static content path: {www}");Console.WriteLine($"HTTPS server website: https://localhost:{port}/api/index.html");Console.WriteLine();// Create and prepare a new SSL server contextvarcontext=newSslContext(SslProtocols.Tls12,newX509Certificate2("server.pfx","qwerty"));// Create a new HTTP servervarserver=newHttpsCacheServer(context,IPAddress.Any,port);server.AddStaticContent(www,"/api");// 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(string.IsNullOrEmpty(line))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!");}}}

Example: HTTPS client

Here comes the example of the HTTPS client. It allows to send HTTP requests (GET, POST, PUT and DELETE) and receive HTTP responses with secured transport protocol.

usingSystem;usingSystem.Security.Authentication;usingSystem.Security.Cryptography.X509Certificates;usingNetCoreServer;namespaceHttpsClient{classProgram{staticvoidMain(string[]args){// HTTPS server addressstringaddress="127.0.0.1";if(args.Length>0)address=args[0];// HTTPS server portintport=8443;if(args.Length>1)port=int.Parse(args[1]);Console.WriteLine($"HTTPS server address: {address}");Console.WriteLine($"HTTPS server port: {port}");Console.WriteLine();// Create and prepare a new SSL client contextvarcontext=newSslContext(SslProtocols.Tls12,newX509Certificate2("client.pfx","qwerty"),(sender,certificate,chain,sslPolicyErrors)=>true);// Create a new HTTPS clientvarclient=newHttpsClientEx(context,address,port);Console.WriteLine("Press Enter to stop the client or '!' to reconnect the client...");// Perform text inputfor(;;){stringline=Console.ReadLine();if(string.IsNullOrEmpty(line))break;// Reconnect the clientif(line=="!"){Console.Write("Client reconnecting...");if(client.IsConnected)client.ReconnectAsync();elseclient.ConnectAsync();Console.WriteLine("Done!");continue;}varcommands=line.Split(' ');if(commands.Length<2){Console.WriteLine("HTTP method and URL must be entered!");continue;}if(commands[0].ToUpper()=="HEAD"){varresponse=client.SendHeadRequest(commands[1]).Result;Console.WriteLine(response);}elseif(commands[0].ToUpper()=="GET"){varresponse=client.SendGetRequest(commands[1]).Result;Console.WriteLine(response);}elseif(commands[0].ToUpper()=="POST"){if(commands.Length<3){Console.WriteLine("HTTP method, URL and body must be entered!");continue;}varresponse=client.SendPostRequest(commands[1],commands[2]).Result;Console.WriteLine(response);}elseif(commands[0].ToUpper()=="PUT"){if(commands.Length<3){Console.WriteLine("HTTP method, URL and body must be entered!");continue;}varresponse=client.SendPutRequest(commands[1],commands[2]).Result;Console.WriteLine(response);}elseif(commands[0].ToUpper()=="DELETE"){varresponse=client.SendDeleteRequest(commands[1]).Result;Console.WriteLine(response);}elseif(commands[0].ToUpper()=="OPTIONS"){varresponse=client.SendOptionsRequest(commands[1]).Result;Console.WriteLine(response);}elseif(commands[0].ToUpper()=="TRACE"){varresponse=client.SendTraceRequest(commands[1]).Result;Console.WriteLine(response);}elseConsole.WriteLine("Unknown HTTP method");}// Disconnect the clientConsole.Write("Client disconnecting...");client.Disconnect();Console.WriteLine("Done!");}}}

Example: WebSocket chat server

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

Use the following link to open WebSocket chat server example: http://localhost:8080/chat/index.html

ws-chat

usingSystem;usingSystem.Net;usingSystem.Net.Sockets;usingSystem.Text;usingNetCoreServer;namespaceWsChatServer{classChatSession:WsSession{publicChatSession(WsServerserver):base(server){}publicoverridevoidOnWsConnected(HttpRequestrequest){Console.WriteLine($"Chat WebSocket session with Id {Id} connected!");// Send invite messagestringmessage="Hello from WebSocket chat! Please send a message or '!' to disconnect the client!";SendTextAsync(message);}publicoverridevoidOnWsDisconnected(){Console.WriteLine($"Chat WebSocket session with Id {Id} disconnected!");}publicoverridevoidOnWsReceived(byte[]buffer,longoffset,longsize){stringmessage=Encoding.UTF8.GetString(buffer,(int)offset,(int)size);Console.WriteLine("Incoming: "+message);// Multicast message to all connected sessions((WsServer)Server).MulticastText(message);// If the buffer starts with '!' the disconnect the current sessionif(message=="!")Close(1000);}protectedoverridevoidOnError(SocketErrorerror){Console.WriteLine($"Chat WebSocket session caught an error with code {error}");}}classChatServer:WsServer{publicChatServer(IPAddressaddress,intport):base(address,port){}protectedoverrideTcpSessionCreateSession(){returnnewChatSession(this);}protectedoverridevoidOnError(SocketErrorerror){Console.WriteLine($"Chat WebSocket server caught an error with code {error}");}}classProgram{staticvoidMain(string[]args){// WebSocket server portintport=8080;if(args.Length>0)port=int.Parse(args[0]);// WebSocket server content pathstringwww="../../../../../www/ws";if(args.Length>1)www=args[1];Console.WriteLine($"WebSocket server port: {port}");Console.WriteLine($"WebSocket server static content path: {www}");Console.WriteLine($"WebSocket server website: http://localhost:{port}/chat/index.html");Console.WriteLine();// Create a new WebSocket servervarserver=newChatServer(IPAddress.Any,port);server.AddStaticContent(www,"/chat");// 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(string.IsNullOrEmpty(line))break;// Restart the serverif(line=="!"){Console.Write("Server restarting...");server.Restart();Console.WriteLine("Done!");}// Multicast admin message to all sessionsline="(admin) "+line;server.MulticastText(line);}// Stop the serverConsole.Write("Server stopping...");server.Stop();Console.WriteLine("Done!");}}}

Example: WebSocket chat client

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

usingSystem;usingSystem.Net.Sockets;usingSystem.Text;usingSystem.Threading;usingNetCoreServer;namespaceWsChatClient{classChatClient:WsClient{publicChatClient(stringaddress,intport):base(address,port){}publicvoidDisconnectAndStop(){_stop=true;CloseAsync(1000);while(IsConnected)Thread.Yield();}publicoverridevoidOnWsConnecting(HttpRequestrequest){request.SetBegin("GET","/");request.SetHeader("Host","localhost");request.SetHeader("Origin","http://localhost");request.SetHeader("Upgrade","websocket");request.SetHeader("Connection","Upgrade");request.SetHeader("Sec-WebSocket-Key",Convert.ToBase64String(WsNonce));request.SetHeader("Sec-WebSocket-Protocol","chat, superchat");request.SetHeader("Sec-WebSocket-Version","13");}publicoverridevoidOnWsConnected(HttpResponseresponse){Console.WriteLine($"Chat WebSocket client connected a new session with Id {Id}");}publicoverridevoidOnWsDisconnected(){Console.WriteLine($"Chat WebSocket client disconnected a session with Id {Id}");}publicoverridevoidOnWsReceived(byte[]buffer,longoffset,longsize){Console.WriteLine($"Incoming: {Encoding.UTF8.GetString(buffer,(int)offset,(int)size)}");}protectedoverridevoidOnDisconnected(){base.OnDisconnected();Console.WriteLine($"Chat WebSocket client disconnected a session with Id {Id}");// Wait for a while...Thread.Sleep(1000);// Try to connect againif(!_stop)ConnectAsync();}protectedoverridevoidOnError(SocketErrorerror){Console.WriteLine($"Chat WebSocket client caught an error with code {error}");}privatebool_stop;}classProgram{staticvoidMain(string[]args){// WebSocket server addressstringaddress="127.0.0.1";if(args.Length>0)address=args[0];// WebSocket server portintport=8080;if(args.Length>1)port=int.Parse(args[1]);Console.WriteLine($"WebSocket server address: {address}");Console.WriteLine($"WebSocket server port: {port}");Console.WriteLine();// Create a new TCP chat clientvarclient=newChatClient(address,port);// Connect the clientConsole.Write("Client connecting...");client.ConnectAsync();Console.WriteLine("Done!");Console.WriteLine("Press Enter to stop the client or '!' to reconnect the client...");// Perform text inputfor(;;){stringline=Console.ReadLine();if(string.IsNullOrEmpty(line))break;// Disconnect the clientif(line=="!"){Console.Write("Client disconnecting...");client.DisconnectAsync();Console.WriteLine("Done!");continue;}// Send the entered text to the chat serverclient.SendTextAsync(line);}// Disconnect the clientConsole.Write("Client disconnecting...");client.DisconnectAndStop();Console.WriteLine("Done!");}}}

Example: WebSocket secure chat server

Here comes the example of the WebSocket secure chat server. It handles multiple WebSocket secure 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 WebSocket one except the code that prepares WebSocket secure context and handshake handler.

Use the following link to open WebSocket secure chat server example: https://localhost:8443/chat/index.html

wss-chat

usingSystem;usingSystem.Net;usingSystem.Net.Sockets;usingSystem.Security.Authentication;usingSystem.Security.Cryptography.X509Certificates;usingSystem.Text;usingNetCoreServer;namespaceWssChatServer{classChatSession:WssSession{publicChatSession(WssServerserver):base(server){}publicoverridevoidOnWsConnected(HttpRequestrequest){Console.WriteLine($"Chat WebSocket session with Id {Id} connected!");// Send invite messagestringmessage="Hello from WebSocket chat! Please send a message or '!' to disconnect the client!";SendTextAsync(message);}publicoverridevoidOnWsDisconnected(){Console.WriteLine($"Chat WebSocket session with Id {Id} disconnected!");}publicoverridevoidOnWsReceived(byte[]buffer,longoffset,longsize){stringmessage=Encoding.UTF8.GetString(buffer,(int)offset,(int)size);Console.WriteLine("Incoming: "+message);// Multicast message to all connected sessions((WssServer)Server).MulticastText(message);// If the buffer starts with '!' the disconnect the current sessionif(message=="!")Close(1000);}protectedoverridevoidOnError(SocketErrorerror){Console.WriteLine($"Chat WebSocket session caught an error with code {error}");}}classChatServer:WssServer{publicChatServer(SslContextcontext,IPAddressaddress,intport):base(context,address,port){}protectedoverrideSslSessionCreateSession(){returnnewChatSession(this);}protectedoverridevoidOnError(SocketErrorerror){Console.WriteLine($"Chat WebSocket server caught an error with code {error}");}}classProgram{staticvoidMain(string[]args){// WebSocket server portintport=8443;if(args.Length>0)port=int.Parse(args[0]);// WebSocket server content pathstringwww="../../../../../www/wss";if(args.Length>1)www=args[1];Console.WriteLine($"WebSocket server port: {port}");Console.WriteLine($"WebSocket server static content path: {www}");Console.WriteLine($"WebSocket server website: https://localhost:{port}/chat/index.html");Console.WriteLine();// Create and prepare a new SSL server contextvarcontext=newSslContext(SslProtocols.Tls12,newX509Certificate2("server.pfx","qwerty"));// Create a new WebSocket servervarserver=newChatServer(context,IPAddress.Any,port);server.AddStaticContent(www,"/chat");// 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(string.IsNullOrEmpty(line))break;// Restart the serverif(line=="!"){Console.Write("Server restarting...");server.Restart();Console.WriteLine("Done!");}// Multicast admin message to all sessionsline="(admin) "+line;server.MulticastText(line);}// Stop the serverConsole.Write("Server stopping...");server.Stop();Console.WriteLine("Done!");}}}

Example: WebSocket secure chat client

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

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

usingSystem;usingSystem.Net.Sockets;usingSystem.Security.Authentication;usingSystem.Security.Cryptography.X509Certificates;usingSystem.Text;usingSystem.Threading;usingNetCoreServer;namespaceWssChatClient{classChatClient:WssClient{publicChatClient(SslContextcontext,stringaddress,intport):base(context,address,port){}publicvoidDisconnectAndStop(){_stop=true;CloseAsync(1000);while(IsConnected)Thread.Yield();}publicoverridevoidOnWsConnecting(HttpRequestrequest){request.SetBegin("GET","/");request.SetHeader("Host","localhost");request.SetHeader("Origin","http://localhost");request.SetHeader("Upgrade","websocket");request.SetHeader("Connection","Upgrade");request.SetHeader("Sec-WebSocket-Key",Convert.ToBase64String(WsNonce));request.SetHeader("Sec-WebSocket-Protocol","chat, superchat");request.SetHeader("Sec-WebSocket-Version","13");}publicoverridevoidOnWsConnected(HttpResponseresponse){Console.WriteLine($"Chat WebSocket client connected a new session with Id {Id}");}publicoverridevoidOnWsDisconnected(){Console.WriteLine($"Chat WebSocket client disconnected a session with Id {Id}");}publicoverridevoidOnWsReceived(byte[]buffer,longoffset,longsize){Console.WriteLine($"Incoming: {Encoding.UTF8.GetString(buffer,(int)offset,(int)size)}");}protectedoverridevoidOnDisconnected(){base.OnDisconnected();Console.WriteLine($"Chat WebSocket client disconnected a session with Id {Id}");// Wait for a while...Thread.Sleep(1000);// Try to connect againif(!_stop)ConnectAsync();}protectedoverridevoidOnError(SocketErrorerror){Console.WriteLine($"Chat WebSocket client caught an error with code {error}");}privatebool_stop;}classProgram{staticvoidMain(string[]args){// WebSocket server addressstringaddress="127.0.0.1";if(args.Length>0)address=args[0];// WebSocket server portintport=8443;if(args.Length>1)port=int.Parse(args[1]);Console.WriteLine($"WebSocket server address: {address}");Console.WriteLine($"WebSocket server port: {port}");Console.WriteLine();// Create and prepare a new SSL client contextvarcontext=newSslContext(SslProtocols.Tls12,newX509Certificate2("client.pfx","qwerty"),(sender,certificate,chain,sslPolicyErrors)=>true);// Create a new TCP chat clientvarclient=newChatClient(context,address,port);// Connect the clientConsole.Write("Client connecting...");client.ConnectAsync();Console.WriteLine("Done!");Console.WriteLine("Press Enter to stop the client or '!' to reconnect the client...");// Perform text inputfor(;;){stringline=Console.ReadLine();if(string.IsNullOrEmpty(line))break;// Reconnect the clientif(line=="!"){Console.Write("Client reconnecting...");if(client.IsConnected)client.ReconnectAsync();elseclient.ConnectAsync();Console.WriteLine("Done!");continue;}// Send the entered text to the chat serverclient.SendTextAsync(line);}// Disconnect the clientConsole.Write("Client disconnecting...");client.DisconnectAndStop();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: 24.011 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 clients: 1
Working messages: 1000
Message size: 32
Seconds to benchmarking: 10
Errors: 0
Total time: 10.024 s
Total data: 2.831 GiB
Total messages: 94369133
Data throughput: 287.299 MiB/s
Message latency: 106 ns
Message throughput: 9413997 msg/s
Server address: 127.0.0.1
Server port: 1111
Working clients: 100
Working messages: 1000
Message size: 32
Seconds to benchmarking: 10
Errors: 0
Total time: 10.189 s
Total data: 1.794 GiB
Total messages: 59585544
Data throughput: 178.463 MiB/s
Message latency: 171 ns
Message throughput: 5847523 msg/s

SSL echo server

Server address: 127.0.0.1
Server port: 2222
Working clients: 1
Working messages: 1000
Message size: 32
Seconds to benchmarking: 10
Errors: 0
Total time: 2.645 s
Total data: 373.329 MiB
Total messages: 12233021
Data throughput: 141.095 MiB/s
Message latency: 216 ns
Message throughput: 4623352 msg/s
Server address: 127.0.0.1
Server port: 2222
Working clients: 100
Working messages: 1000
Message size: 32
Seconds to benchmarking: 10
Errors: 0
Total time: 10.060 s
Total data: 1.472 GiB
Total messages: 49029133
Data throughput: 148.741 MiB/s
Message latency: 205 ns
Message throughput: 4873398 msg/s

UDP echo server

Server address: 127.0.0.1
Server port: 3333
Working clients: 1
Working messages: 1000
Message size: 32
Seconds to benchmarking: 10
Errors: 0
Total time: 10.032 s
Total data: 33.994 MiB
Total messages: 1113182
Data throughput: 3.395 MiB/s
Message latency: 9.012 mcs
Message throughput: 110960 msg/s
Server address: 127.0.0.1
Server port: 3333
Working clients: 100
Working messages: 1000
Message size: 32
Seconds to benchmarking: 10
Errors: 0
Total time: 10.635 s
Total data: 20.355 MiB
Total messages: 666791
Data throughput: 1.934 MiB/s
Message latency: 15.950 mcs
Message throughput: 62693 msg/s

WebSocket echo server

Server address: 127.0.0.1
Server port: 8080
Working clients: 1
Working messages: 1000
Message size: 32
Seconds to benchmarking: 10
Errors: 0
Total time: 3.037 s
Total data: 105.499 MiB
Total messages: 3456618
Data throughput: 34.742 MiB/s
Message latency: 878 ns
Message throughput: 1137864 msg/s
Server address: 127.0.0.1
Server port: 8080
Working clients: 100
Working messages: 1000
Message size: 32
Seconds to benchmarking: 10
Errors: 0
Total time: 10.078 s
Total data: 426.803 MiB
Total messages: 13984888
Data throughput: 42.353 MiB/s
Message latency: 720 ns
Message throughput: 1387555 msg/s

WebSocket secure echo server

Server address: 127.0.0.1
Server port: 8443
Working clients: 1
Working messages: 1000
Message size: 32
Seconds to benchmarking: 10
Errors: 0
Total time: 10.030 s
Total data: 198.103 MiB
Total messages: 6491390
Data throughput: 19.767 MiB/s
Message latency: 1.545 mcs
Message throughput: 647153 msg/s
Server address: 127.0.0.1
Server port: 8443
Working clients: 100
Working messages: 1000
Message size: 32
Seconds to benchmarking: 10
Errors: 0
Total time: 10.112 s
Total data: 405.286 MiB
Total messages: 13280221
Data throughput: 40.078 MiB/s
Message latency: 761 ns
Message throughput: 1313228 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 clients: 1
Message size: 32
Seconds to benchmarking: 10
Errors: 0
Total time: 10.022 s
Total data: 407.023 MiB
Total messages: 13337326
Data throughput: 40.625 MiB/s
Message latency: 751 ns
Message throughput: 1330734 msg/s
Server address: 127.0.0.1
Server port: 1111
Working clients: 100
Message size: 32
Seconds to benchmarking: 10
Errors: 0
Total time: 10.112 s
Total data: 421.348 MiB
Total messages: 13806493
Data throughput: 41.681 MiB/s
Message latency: 732 ns
Message throughput: 1365280 msg/s

SSL multicast server

Server address: 127.0.0.1
Server port: 2222
Working clients: 1
Message size: 32
Seconds to benchmarking: 10
Errors: 0
Total time: 10.024 s
Total data: 325.225 MiB
Total messages: 10656801
Data throughput: 32.453 MiB/s
Message latency: 940 ns
Message throughput: 1063075 msg/s
Server address: 127.0.0.1
Server port: 2222
Working clients: 100
Message size: 32
Seconds to benchmarking: 10
Errors: 0
Total time: 10.144 s
Total data: 343.460 MiB
Total messages: 11254173
Data throughput: 33.876 MiB/s
Message latency: 901 ns
Message throughput: 1109393 msg/s

UDP multicast server

Server address: 239.255.0.1
Server port: 3333
Working clients: 1
Message size: 32
Seconds to benchmarking: 10
Errors: 0
Total time: 10.026 s
Total data: 13.225 MiB
Total messages: 433202
Data throughput: 1.326 MiB/s
Message latency: 23.145 mcs
Message throughput: 43205 msg/s
Server address: 239.255.0.1
Server port: 3333
Working clients: 100
Message size: 32
Seconds to benchmarking: 10
Errors: 0
Total time: 10.035 s
Total data: 28.684 MiB
Total messages: 939408
Data throughput: 2.877 MiB/s
Message latency: 10.682 mcs
Message throughput: 93606 msg/s

WebSocket multicast server

Server address: 127.0.0.1
Server port: 8080
Working clients: 1
Message size: 32
Seconds to benchmarking: 10
Errors: 0
Total time: 10.048 s
Total data: 183.108 MiB
Total messages: 6000000
Data throughput: 18.228 MiB/s
Message latency: 1.674 mcs
Message throughput: 597121 msg/s
Server address: 127.0.0.1
Server port: 8080
Working clients: 100
Message size: 32
Seconds to benchmarking: 10
Errors: 0
Total time: 10.227 s
Total data: 125.957 MiB
Total messages: 4126627
Data throughput: 12.320 MiB/s
Message latency: 2.478 mcs
Message throughput: 403466 msg/s

WebSocket secure multicast server

Server address: 127.0.0.1
Server port: 8443
Working clients: 1
Message size: 32
Seconds to benchmarking: 10
Errors: 0
Total time: 10.034 s
Total data: 184.159 MiB
Total messages: 6034421
Data throughput: 18.359 MiB/s
Message latency: 1.662 mcs
Message throughput: 601338 msg/s
Server address: 127.0.0.1
Server port: 8443
Working clients: 100
Message size: 32
Seconds to benchmarking: 10
Errors: 0
Total time: 10.171 s
Total data: 315.306 MiB
Total messages: 10331721
Data throughput: 30.1022 MiB/s
Message latency: 984 ns
Message throughput: 1015763 msg/s

Benchmark: Web Server

HTTP Trace server

Server address: 127.0.0.1
Server port: 8080
Working clients: 1
Working messages: 1
Seconds to benchmarking: 10
Errors: 0
Total time: 10.023 s
Total data: 10.987 MiB
Total messages: 108465
Data throughput: 1.096 MiB/s
Message latency: 92.414 mcs
Message throughput: 10820 msg/s
Server address: 127.0.0.1
Server port: 8080
Working clients: 100
Working messages: 1
Seconds to benchmarking: 10
Errors: 0
Total time: 10.085 s
Total data: 40.382 MiB
Total messages: 401472
Data throughput: 4.003 MiB/s
Message latency: 25.120 mcs
Message throughput: 39807 msg/s

HTTPS Trace server

Server address: 127.0.0.1
Server port: 8443
Working clients: 1
Working messages: 1
Seconds to benchmarking: 10
Errors: 0
Total time: 595.214 ms
Total data: 627.842 KiB
Total messages: 6065
Data throughput: 1.030 MiB/s
Message latency: 98.139 mcs
Message throughput: 10189 msg/s
Server address: 127.0.0.1
Server port: 8443
Working clients: 100
Working messages: 1
Seconds to benchmarking: 10
Errors: 0
Total time: 3.548 s
Total data: 17.948 MiB
Total messages: 179111
Data throughput: 5.052 MiB/s
Message latency: 19.813 mcs
Message throughput: 50471 msg/s

OpenSSL certificates

In order to create OpenSSL based server and client you should prepare a set of SSL certificates.

Production

Depending on your project, you may need to purchase a traditional SSL certificate signed by a Certificate Authority. If you, for instance, want some else's web browser to talk to your WebSocket project, you'll need a traditional SSL certificate.

Development

The commands below entered in the order they are listed will generate a self-signed certificate for development or testing purposes.

If you want to save some time, download and run Generate-Certs and it will generate the certs for you in less than a minute. Supports Windows + Linux.

If you'd rather enter in the commands to generate the certificates manually, here is the list in order below.

Certificate Authority

  • Create CA private key
openssl genrsa -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
  • Convert CA self-signed certificate to PFX
openssl pkcs12 -export -passout pass:qwerty -inkey ca.key -in ca.crt -out ca.pfx
  • Convert CA self-signed certificate to PEM
openssl pkcs12 -passin pass:qwerty -passout pass:qwerty -in ca.pfx -out ca.pem

SSL Server certificate

  • Create private key for the server
openssl genrsa -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
  • 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 PFX
openssl pkcs12 -export -passout pass:qwerty -inkey server.key -in server.crt -out server.pfx
  • Convert the server certificate to PEM
openssl pkcs12 -passin pass:qwerty -passout pass:qwerty -in server.pfx -out server.pem

SSL Client certificate

  • Create private key for the client
openssl genrsa -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
  • 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 PFX
openssl pkcs12 -export -passout pass:qwerty -inkey client.key -in client.crt -out client.pfx
  • Convert the client certificate to PEM
openssl pkcs12 -passin pass:qwerty -passout pass:qwerty -in client.pfx -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, HTTP, HTTPS, WebSocket protocols and 10K connections problem solution

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages