How create multiclient(multithread) SSL Socket Server C# ?
12 Apr 2015, 12:53
Hello All,
How create SSL multiuser or multithread server (multiple connection) from this code:
or maybe someone know good example but only SSL version ?
using System;
using System.Collections;
using System.Net;
using System.Net.Sockets;
using System.Net.Security;
using System.Security.Authentication;
using System.Text;
using System.Security.Cryptography.X509Certificates;
using System.IO;
namespace SSLServer
{
public sealed class SslTcpServer
{
static X509Certificate serverCertificate = null;
public static void RunServer(string certificate)
{
// StartSSL.com certs pfx(p12) file with cert: CN=ssl.domain.com
serverCertificate = new X509Certificate2("ssl.p12", "KeyPassword");
// Create a TCP/IP (IPv4) socket and listen for incoming connections.
TcpListener listener = new TcpListener(IPAddress.Any, 8080);
listener.Start();
while (true)
{
Console.WriteLine("Waiting for a client to connect...");
// Application blocks while waiting for an incoming connection.
// Type CNTL-C to terminate the server.
TcpClient client = listener.AcceptTcpClient();
ProcessClient(client);
}
}
static void ProcessClient(TcpClient client)
{
SslStream sslStream = new SslStream(client.GetStream(), false);
try
{
sslStream.AuthenticateAsServer(serverCertificate, false, SslProtocols.Tls, true);
sslStream.ReadTimeout = 5000;
sslStream.WriteTimeout = 5000;
// Read a message from the client.
Console.WriteLine("Waiting for client message...");
string messageData = ReadMessage(sslStream);
Console.WriteLine("Received: {0}", messageData);
// Write a message to the client.
byte[] message = Encoding.UTF8.GetBytes("Hello from the server.");
Console.WriteLine("Sending hello message.");
sslStream.Write(message);
}
catch (AuthenticationException e)
{
Console.WriteLine("Exception: {0}", e.Message);
if (e.InnerException != null)
{
Console.WriteLine("Inner exception: {0}", e.InnerException.Message);
}
Console.WriteLine("Authentication failed - closing the connection.");
sslStream.Close();
client.Close();
return;
}
finally
{
sslStream.Close();
client.Close();
}
}
static string ReadMessage(SslStream sslStream)
{
// Read the message sent by the client.
// The client signals the end of the message using the
// "" marker.
byte[] buffer = new byte[2048];
StringBuilder messageData = new StringBuilder();
int bytes = -1;
do
{
// Read the client's test message.
bytes = sslStream.Read(buffer, 0, buffer.Length);
// Use Decoder class to convert from bytes to UTF8
// in case a character spans two buffers.
Decoder decoder = Encoding.UTF8.GetDecoder();
char[] chars = new char[decoder.GetCharCount(buffer, 0, bytes)];
decoder.GetChars(buffer, 0, bytes, chars, 0);
messageData.Append(chars);
// Check for EOF or an empty message.
if (messageData.ToString().IndexOf("") != -1)
{
break;
}
} while (bytes != 0);
return messageData.ToString();
}
public static void Main(string[] args)
{
string certificate = "";
try
{
SslTcpServer.RunServer(certificate);
}
catch (Exception e)
{
Console.WriteLine("error");
Console.ReadLine();
}
//return 0;
}
}
}
Thanks ...
Bye.
Replies
mindbreaker
13 Apr 2015, 14:33
RE:
Paul_Hayes said:
Hi,
If you are using the .NET framework version 4.5 look into the Task Parallel Library
The Task Parallel Library (TPL) is based on the concept of a task, which represents an asynchronous operation. In some ways, a task resembles a thread or ThreadPool work item, but at a higher level of abstraction. The term task parallelism refers to one or more independent tasks running concurrently
https://msdn.microsoft.com/en-us/library/dd537609%28v=vs.110%29.aspx
Just refactor your code to implement this architecture.
Thank you very much.
@mindbreaker
mindbreaker
15 Apr 2015, 17:11
sslstream end
Hi all,
Multi ssl server and client from calgo
It does not work correctly client dont Print server message why?
Client:
// System
using System;
using System.IO;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
// cAlgo
using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
using cAlgo.API.Requests;
using cAlgo.Indicators;
using System.Collections;
using System.Collections.Generic;
using System.Net.Security;
using System.Net.Sockets;
using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;
namespace cAlgo
{
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.FullAccess)]
public class OnePositionClient : Robot
{
[Parameter("Username", DefaultValue = "")]
public string Username { get; set; }
[Parameter("Password", DefaultValue = "")]
public string Password { get; set; }
[Parameter("MoneyForSignalUSD", DefaultValue = 100, MinValue = 100)]
public int MoneyForSignalUSD { get; set; }
List<string> PosOpenID = new List<string>();
List<string> PosCloseID = new List<string>();
List<string> PosServerID = new List<string>();
List<string> PosServerAll = new List<string>();
public static string txt = "";
private static Hashtable certificateErrors = new Hashtable();
protected override void OnTick()
{
ConnectSSL("HelloServer" + Symbol);
}
//================================================================================================================
// End Send POST to HTTPS Server
//================================================================================================================
// The following method is invoked by the RemoteCertificateValidationDelegate.
public static bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
if (sslPolicyErrors == SslPolicyErrors.None)
return true;
Console.WriteLine("Certificate error: {0}", sslPolicyErrors);
// Do not allow this client to communicate with unauthenticated servers.
//return false;
//Force ssl certyfikates as correct
return true;
}
public void ConnectSSL(string msg = "")
{
txt = "";
try
{
TcpClient client = new TcpClient("localhost", 8080);
// Create an SSL stream that will close the client's stream.
SslStream sslStream = new SslStream(client.GetStream(), false, new RemoteCertificateValidationCallback(ValidateServerCertificate), null);
try
{
sslStream.AuthenticateAsClient("ssl.breakermind.com");
} catch (AuthenticationException e)
{
Console.WriteLine("Exception: {0}", e.Message);
if (e.InnerException != null)
{
Console.WriteLine("Inner exception: {0}", e.InnerException.Message);
}
Console.WriteLine("Authentication failed - closing the connection.");
client.Close();
return;
}
int j = 10;
byte[] messsage = Encoding.UTF8.GetBytes(msg + (char)j);
// Send hello message to the server.
Print("Send msg " + msg);
sslStream.Write(messsage);
sslStream.Flush();
// Read message from the server.
int i = -1;
while ((i = sslStream.ReadByte()) != 10)
{
txt = txt + (char)i;
if (i == -1)
{
Console.WriteLine("Server says: {0}", txt);
break;
}
}
Console.WriteLine("Server says: {0}", txt);
// Close the client connection.
client.Close();
Console.WriteLine("Client closed.");
} catch (ArgumentNullException e)
{
Print("ArgumentNullException: {0}", e);
} catch (SocketException e)
{
Print("SocketException: {0}", e);
}
}
public void Connect(string PosAll = "")
{
///===========================================================
string pos = "SET#" + "1#";
//pos = pos + "SPREAD:" + Symbol.Spread + "|";
pos = pos + PosAll;
// end of stream
pos = pos + '\0';
// Process the data sent by the client.
Print("String " + pos);
////===========================================================
try
{
TcpClient client = new TcpClient("localhost", 8080);
Byte[] data = System.Text.Encoding.ASCII.GetBytes(pos);
NetworkStream stream = client.GetStream();
stream.Write(data, 0, data.Length);
Print("Sent: " + pos);
data = new Byte[1024];
Int32 bytes = stream.Read(data, 0, data.Length);
string responseData = System.Text.Encoding.ASCII.GetString(data, 0, bytes);
Print("Received: {0}", responseData);
// Close everything.
stream.Close();
client.Close();
} catch (ArgumentNullException e)
{
Print("ArgumentNullException: {0}", e);
} catch (SocketException e)
{
Print("SocketException: {0}", e);
}
}
}
}
//====================================================================================================================
// Initialize Positions
//====================================================================================================================
Server multi ssl
using System;
using System.Threading;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Text.RegularExpressions;
using System.IO;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.Security.Authentication;
namespace server
{
public class server
{
private string positions = "";
// Declare a two dimensional array
// users allowed 10
private static int maxSlots = 11;
private string[,] posArray = new string[maxSlots + 1, 1];
X509Certificate serverCertificate = new X509Certificate2("ssl.p12", "KeyPass");
ManualResetEvent tcpClientConnected = new ManualResetEvent(false);
static void DisplayCertificateInformation(SslStream stream)
{
Console.WriteLine("Certificate revocation list checked: {0}", stream.CheckCertRevocationStatus);
X509Certificate localCertificate = stream.LocalCertificate;
if (stream.LocalCertificate != null)
{
Console.WriteLine("Local cert was issued to {0} and is valid from {1} until {2}.",
localCertificate.Subject,
localCertificate.GetEffectiveDateString(),
localCertificate.GetExpirationDateString());
}
else
{
Console.WriteLine("Local certificate is null.");
}
// Display the properties of the client's certificate.
X509Certificate remoteCertificate = stream.RemoteCertificate;
if (stream.RemoteCertificate != null)
{
Console.WriteLine("Remote cert was issued to {0} and is valid from {1} until {2}.",
remoteCertificate.Subject,
remoteCertificate.GetEffectiveDateString(),
remoteCertificate.GetExpirationDateString());
}
else
{
Console.WriteLine("Remote certificate is null.");
}
}
static string ReadMessage(SslStream sslStream)
{
// Read the message sent by the client.
// The client signals the end of the message using the
// "" marker.
StringBuilder messageData = new StringBuilder();
int bytes = -1;
do
{
// Read the client's test message.
bytes = sslStream.ReadByte();
// Use Decoder class to convert from bytes to UTF8
// in case a character spans two buffers.
Decoder decoder = Encoding.UTF8.GetDecoder();
char znak = (char)bytes;
messageData.Append(znak);
// Check for EOF or an empty message.
if (messageData.ToString().IndexOf("") != -1)
{
break;
}
} while (bytes != 0);
return messageData.ToString();
}
void ProcessIncomingData(object obj)
{
SslStream sslStream = (SslStream)obj;
//string ip = ((IPEndPoint)client.Client.RemoteEndPoint).Address.ToString();
//Console.WriteLine("Client IP : " + ip);
string sb = "";
int i = -1;
try
{
while (true)
{
int j = 10;
//Console.WriteLine((char)j);
while ((i = sslStream.ReadByte()) != 10)
{
sb = sb + (char)i;
// Console.WriteLine("Stream in char " + i);
if (i == -1) break;
}
Console.WriteLine("Client " + sb);
byte[] messsage = Encoding.UTF8.GetBytes("Helloclient" + (char)j);
// Send hello message to the server.
sslStream.Write(messsage);
sslStream.Flush();
}
}
catch (Exception e) { }
}
void ProcessIncomingConnection(IAsyncResult ar)
{
TcpListener listener = (TcpListener)ar.AsyncState;
TcpClient client = listener.EndAcceptTcpClient(ar);
SslStream sslStream = new SslStream(client.GetStream(), false);
try
{
sslStream.AuthenticateAsServer(serverCertificate, false, SslProtocols.Tls, true);
//DisplayCertificateInformation(sslStream);
}catch(Exception e){
Console.WriteLine("Client no ssl" + client);
client.Close();
}
ThreadPool.QueueUserWorkItem(ProcessIncomingData, sslStream);
tcpClientConnected.Set();
}
public void start()
{
IPEndPoint endpoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8080);
TcpListener listener = new TcpListener(endpoint);
listener.Start();
while (true)
{
tcpClientConnected.Reset();
listener.BeginAcceptTcpClient(new AsyncCallback(ProcessIncomingConnection), listener);
tcpClientConnected.WaitOne();
}
}
}
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Multi user server. Recive save and send data to clients max 10 accounts.");
//DateTime.Now.ToLongTimeString()
Console.WriteLine(DateTime.Now + " Waiting for connections....");
try
{
server s = new server();
s.start();
}
catch (Exception e) { }
}
}
}
Thanks.
@mindbreaker
mindbreaker
15 Apr 2015, 18:22
Working
Works (SSL cAlgo Client send Symbol Bid Ask to the Server C#):
Server SSL C# MultiConnection
Server.cs
using System;
using System.Threading;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Text.RegularExpressions;
using System.IO;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.Security.Authentication;
namespace server
{
public class server
{
private string positions = "";
// Declare a two dimensional array
// users allowed 10
private static int maxSlots = 11;
private string[,] posArray = new string[maxSlots + 1, 1];
X509Certificate serverCertificate = new X509Certificate2("ssl.p12", "KeyPass");
ManualResetEvent tcpClientConnected = new ManualResetEvent(false);
static void DisplayCertificateInformation(SslStream stream)
{
Console.WriteLine("Certificate revocation list checked: {0}", stream.CheckCertRevocationStatus);
X509Certificate localCertificate = stream.LocalCertificate;
if (stream.LocalCertificate != null)
{
Console.WriteLine("Local cert was issued to {0} and is valid from {1} until {2}.",
localCertificate.Subject,
localCertificate.GetEffectiveDateString(),
localCertificate.GetExpirationDateString());
}
else
{
Console.WriteLine("Local certificate is null.");
}
// Display the properties of the client's certificate.
X509Certificate remoteCertificate = stream.RemoteCertificate;
if (stream.RemoteCertificate != null)
{
Console.WriteLine("Remote cert was issued to {0} and is valid from {1} until {2}.",
remoteCertificate.Subject,
remoteCertificate.GetEffectiveDateString(),
remoteCertificate.GetExpirationDateString());
}
else
{
Console.WriteLine("Remote certificate is null.");
}
}
static string ReadMessage(SslStream sslStream)
{
// Read the message sent by the client.
// The client signals the end of the message using the
// "<EOF>" marker.
byte [] buffer = new byte[2048];
StringBuilder messageData = new StringBuilder();
int bytes = -1;
do
{
// Read the client's test message.
bytes = sslStream.Read(buffer, 0, buffer.Length);
// Use Decoder class to convert from bytes to UTF8
// in case a character spans two buffers.
Decoder decoder = Encoding.UTF8.GetDecoder();
char[] chars = new char[decoder.GetCharCount(buffer,0,bytes)];
decoder.GetChars(buffer, 0, bytes, chars,0);
messageData.Append (chars);
// Check for EOF or an empty message.
if (messageData.ToString().IndexOf("<EOF>") != -1)
{
break;
}
} while (bytes !=0);
return messageData.ToString();
}
void ProcessIncomingData(object obj)
{
SslStream sslStream = (SslStream)obj;
try{
// Set timeouts for the read and write to 5 seconds.
sslStream.ReadTimeout = 5000;
sslStream.WriteTimeout = 5000;
// Read a message from the client.
Console.WriteLine("Waiting for client message...");
string messageData = ReadMessage(sslStream);
Console.WriteLine("Received: {0}", messageData);
// Write a message to the client.
byte[] message = Encoding.UTF8.GetBytes("Hello from the server.<EOF>");
Console.WriteLine("Sending hello message.");
sslStream.Write(message);
sslStream.Flush();
}
catch (Exception e) { }
}
void ProcessIncomingConnection(IAsyncResult ar)
{
TcpListener listener = (TcpListener)ar.AsyncState;
TcpClient client = listener.EndAcceptTcpClient(ar);
SslStream sslStream = new SslStream(client.GetStream(), false);
try
{
sslStream.AuthenticateAsServer(serverCertificate, false, SslProtocols.Tls, true);
//DisplayCertificateInformation(sslStream);
}
catch (Exception e)
{
Console.WriteLine("Client no ssl" + client);
client.Close();
}
ThreadPool.QueueUserWorkItem(ProcessIncomingData, sslStream);
tcpClientConnected.Set();
}
public void start()
{
IPEndPoint endpoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8080);
TcpListener listener = new TcpListener(endpoint);
listener.Start();
while (true)
{
tcpClientConnected.Reset();
listener.BeginAcceptTcpClient(new AsyncCallback(ProcessIncomingConnection), listener);
tcpClientConnected.WaitOne();
}
}
}
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Multi user server. Recive save and send data to clients max 10 accounts.");
//DateTime.Now.ToLongTimeString()
Console.WriteLine(DateTime.Now + " Waiting for connections....");
try
{
server s = new server();
s.start();
}
catch (Exception e) { }
}
}
}
Client.algo
// System
using System;
using System.IO;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
// cAlgo
using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
using cAlgo.API.Requests;
using cAlgo.Indicators;
using System.Collections;
using System.Collections.Generic;
using System.Net.Security;
using System.Net.Sockets;
using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;
using System.Threading;
namespace cAlgo
{
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.FullAccess)]
public class OnePositionClient : Robot
{
// "Server SSL Certyficate (CN=www.domain.com)"
public string hostname = "www.example.com";
// "Server host www.example.com"
public string host = "www.example.com";
// "Server port"
public int port = 8080;
List<string> PosOpenID = new List<string>();
public static string txt = "";
private static Hashtable certificateErrors = new Hashtable();
protected override void OnBar()
{
ConnectSSL("Hello Server " + Symbol);
}
//================================================================================================================
// SSL Socket client Data send
//================================================================================================================
// The following method is invoked by the RemoteCertificateValidationDelegate.
public static bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
if (sslPolicyErrors == SslPolicyErrors.None)
return true;
Console.WriteLine("Certificate error: {0}", sslPolicyErrors);
// Do not allow this client to communicate with unauthenticated servers when false.
//return false;
//Force ssl certyfikates as correct
return true;
}
static string ReadMessage(SslStream sslStream)
{
// Read the message sent by the server.
// The end of the message is signaled using the
// "<EOF>" marker.
byte[] buffer = new byte[2048];
StringBuilder messageData = new StringBuilder();
int bytes = -1;
do
{
bytes = sslStream.Read(buffer, 0, buffer.Length);
// Use Decoder class to convert from bytes to UTF8
// in case a character spans two buffers.
Decoder decoder = Encoding.UTF8.GetDecoder();
char[] chars = new char[decoder.GetCharCount(buffer, 0, bytes)];
decoder.GetChars(buffer, 0, bytes, chars, 0);
messageData.Append(chars);
// Check for EOF.
if (messageData.ToString().IndexOf("<EOF>") != -1)
{
break;
}
} while (bytes != 0);
return messageData.ToString();
}
public void ConnectSSL(string msg = "")
{
txt = "";
try
{
TcpClient client = new TcpClient(host, port);
// Create an SSL stream that will close the client's stream.
SslStream sslStream = new SslStream(client.GetStream(), false, new RemoteCertificateValidationCallback(ValidateServerCertificate), null);
try
{
sslStream.AuthenticateAsClient(hostname);
} catch (AuthenticationException e)
{
Console.WriteLine("Exception: {0}", e.Message);
if (e.InnerException != null)
{
Print("Inner exception: {0}", e.InnerException.Message);
}
Print("Authentication failed - closing the connection.");
client.Close();
return;
}
// Signal the end of the message using the "<EOF>".
// Semd message
byte[] messsage = Encoding.UTF8.GetBytes(msg + " <EOF>");
// Send hello message to the server.
sslStream.Write(messsage);
sslStream.Flush();
// Read message from the server.
string serverMessage = ReadMessage(sslStream);
Print("Server says: {0}", serverMessage);
// Close the client connection.
client.Close();
Print("Client closed.");
} catch (ArgumentNullException e)
{
Print("ArgumentNullException: {0}", e);
} catch (SocketException e)
{
Print("SocketException: {0}", e);
}
}
}
}
@mindbreaker

ClickAlgo
13 Apr 2015, 09:52
Hi,
If you are using the .NET framework version 4.5 look into the Task Parallel Library
The Task Parallel Library (TPL) is based on the concept of a task, which represents an asynchronous operation. In some ways, a task resembles a thread or ThreadPool work item, but at a higher level of abstraction. The term task parallelism refers to one or more independent tasks running concurrently
https://msdn.microsoft.com/en-us/library/dd537609%28v=vs.110%29.aspx
Just refactor your code to implement this architecture.
@ClickAlgo