some modifications for ClientServerLib
This commit is contained in:
1 parent
ca5fc16332
commit
214cd0f661
17 files changed
+322
-222
No files matched your search
@@ -29,6 +29,8 @@ namespace ClientServerLib
|
||||
private OnSend onSend;
|
||||
private OnReceived onReceived;
|
||||
|
||||
private byte[] data;
|
||||
|
||||
public bool Connected
|
||||
{
|
||||
get { return connected; }
|
||||
@@ -41,14 +43,12 @@ namespace ClientServerLib
|
||||
running = true;
|
||||
requests = new List<SRequest>();
|
||||
responses = new List<SRequest>();
|
||||
data = new byte[bufferLength];
|
||||
|
||||
connection = new CConnection(new TcpClient(), -1);
|
||||
|
||||
clientThread = new Thread(new ThreadStart(Runner));
|
||||
clientThread.Start();
|
||||
}
|
||||
|
||||
public void Connect(string IP = "127.0.0.1", int Port = 3000,
|
||||
public void Connect(string IP = "127.0.0.1", int Port = 3000, string Password = null,
|
||||
OnConnectionChanged OnConnectionChanged = null,
|
||||
OnSend OnSend = null,
|
||||
OnReceived OnReceived = null)
|
||||
@@ -61,7 +61,15 @@ namespace ClientServerLib
|
||||
|
||||
ip = IP;
|
||||
port = Port;
|
||||
connection.Password = Password;
|
||||
doConnect = true;
|
||||
|
||||
if (clientThread == null)
|
||||
{
|
||||
running = true;
|
||||
clientThread = new Thread(new ThreadStart(Runner));
|
||||
clientThread.Start();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,9 +93,13 @@ namespace ClientServerLib
|
||||
|
||||
public void Close()
|
||||
{
|
||||
Disconnect();
|
||||
running = false;
|
||||
clientThread.Join(100);
|
||||
|
||||
if (clientThread != null)
|
||||
clientThread.Join(100);
|
||||
|
||||
clientThread = null;
|
||||
DoDisconnect();
|
||||
}
|
||||
|
||||
public void SendMessage(byte[] Message, ResponseCallback Callback)
|
||||
@@ -111,10 +123,14 @@ namespace ClientServerLib
|
||||
{
|
||||
try
|
||||
{
|
||||
serverEndPoint = new IPEndPoint(IPAddress.Parse(ip), port);
|
||||
connection.TcpClient.Connect(serverEndPoint);
|
||||
connected = true;
|
||||
RaiseOnConnectionChanged();
|
||||
IPAddress resolvedIP;
|
||||
if (TryResolveIPAddress(ip, out resolvedIP))
|
||||
{
|
||||
serverEndPoint = new IPEndPoint(resolvedIP, port);
|
||||
connection.TcpClient.Connect(serverEndPoint);
|
||||
connected = true;
|
||||
RaiseOnConnectionChanged();
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
@@ -122,7 +138,7 @@ namespace ClientServerLib
|
||||
|
||||
for (int i = 0; i < 500; i++)
|
||||
{
|
||||
if (doConnect)
|
||||
if (running && doConnect)
|
||||
Thread.Sleep(10);
|
||||
else
|
||||
break;
|
||||
@@ -141,6 +157,7 @@ namespace ClientServerLib
|
||||
try
|
||||
{
|
||||
Communicate();
|
||||
Thread.Sleep(10);
|
||||
}
|
||||
catch
|
||||
{
|
||||
@@ -148,9 +165,62 @@ namespace ClientServerLib
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (!doConnect && !connected)
|
||||
{
|
||||
for (int i = 0; i < 500; i++)
|
||||
{
|
||||
if (running && !doConnect)
|
||||
Thread.Sleep(10);
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool TryResolveIPAddress(string serverNameOrURL, out IPAddress resolvedIPAddress)
|
||||
{
|
||||
bool isResolved = false;
|
||||
IPHostEntry hostEntry = null;
|
||||
IPAddress resolvIP = null;
|
||||
try
|
||||
{
|
||||
if (!IPAddress.TryParse(serverNameOrURL, out resolvIP))
|
||||
{
|
||||
hostEntry = Dns.GetHostEntry(serverNameOrURL);
|
||||
if (hostEntry != null && hostEntry.AddressList != null && hostEntry.AddressList.Length > 0)
|
||||
{
|
||||
if (hostEntry.AddressList.Length == 1)
|
||||
{
|
||||
resolvIP = hostEntry.AddressList[0];
|
||||
isResolved = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (IPAddress var in hostEntry.AddressList)
|
||||
{
|
||||
if (var.AddressFamily == AddressFamily.InterNetwork)
|
||||
{
|
||||
resolvIP = var;
|
||||
isResolved = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
isResolved = true;
|
||||
}
|
||||
catch (Exception) {}
|
||||
finally
|
||||
{
|
||||
resolvedIPAddress = resolvIP;
|
||||
}
|
||||
return isResolved;
|
||||
}
|
||||
|
||||
private void DoDisconnect()
|
||||
{
|
||||
try
|
||||
@@ -161,6 +231,7 @@ namespace ClientServerLib
|
||||
|
||||
connection = new CConnection(new TcpClient(), -1);
|
||||
connected = false;
|
||||
doConnect = false;
|
||||
RaiseOnConnectionChanged();
|
||||
}
|
||||
|
||||
@@ -170,8 +241,7 @@ namespace ClientServerLib
|
||||
DoDisconnect();
|
||||
|
||||
NetworkStream clientStream = connection.TcpClient.GetStream();
|
||||
|
||||
byte[] data = new byte[bufferLength];
|
||||
|
||||
int bytesRead;
|
||||
|
||||
if (!connection.KeySet)
|
||||
@@ -302,7 +372,10 @@ namespace ClientServerLib
|
||||
{
|
||||
onConnectionChanged(connected);
|
||||
}
|
||||
catch {}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine (e.Message);
|
||||
}
|
||||
}
|
||||
|
||||
private void RaiseOnSend(byte[] Message)
|
||||
|
||||
@@ -14,10 +14,13 @@ namespace ClientServerLib
|
||||
internal class CConnection
|
||||
{
|
||||
private bool keySet;
|
||||
private byte[] key;
|
||||
private bool encryption;
|
||||
private CDiffieHellman dh;
|
||||
private string password;
|
||||
private CDiffieHellman dh;
|
||||
private UTF8Encoding encoder;
|
||||
private int connectionID;
|
||||
private static SHA256Managed SHA256 = new SHA256Managed();
|
||||
|
||||
public TcpClient TcpClient;
|
||||
|
||||
@@ -31,14 +34,26 @@ namespace ClientServerLib
|
||||
get { return connectionID; }
|
||||
}
|
||||
|
||||
public CConnection(TcpClient client, int ConnectionID, bool Encryption = false)
|
||||
public string Password
|
||||
{
|
||||
set
|
||||
{
|
||||
password = value;
|
||||
encryption = value != null;
|
||||
keySet = false;
|
||||
}
|
||||
}
|
||||
|
||||
public CConnection(TcpClient client, int ConnectionID, string Password = null)
|
||||
{
|
||||
TcpClient = client;
|
||||
client.NoDelay = true;
|
||||
keySet = false;
|
||||
encryption = Encryption;
|
||||
encryption = Password != null;
|
||||
password = Password;
|
||||
connectionID = ConnectionID;
|
||||
encoder = new UTF8Encoding();
|
||||
key = null;
|
||||
}
|
||||
|
||||
public byte[] GetKeyParams()
|
||||
@@ -64,11 +79,12 @@ namespace ClientServerLib
|
||||
{
|
||||
encryption = false;
|
||||
keySet = true;
|
||||
key = null;
|
||||
return encoder.GetBytes(response);
|
||||
}
|
||||
|
||||
dh = new CDiffieHellman(256).GenerateResponse(response);
|
||||
|
||||
key = _BuildHash(dh.Key, password);
|
||||
keySet = true;
|
||||
encryption = true;
|
||||
return encoder.GetBytes(dh.ToString());
|
||||
@@ -81,6 +97,7 @@ namespace ClientServerLib
|
||||
if (response == "NO ENCRYPTION")
|
||||
{
|
||||
keySet = true;
|
||||
key = null;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -88,6 +105,7 @@ namespace ClientServerLib
|
||||
return;
|
||||
|
||||
dh.HandleResponse(response);
|
||||
key = _BuildHash(dh.Key, password);
|
||||
keySet = true;
|
||||
}
|
||||
|
||||
@@ -101,6 +119,19 @@ namespace ClientServerLib
|
||||
return _Decompress(_Decrypt(Data));
|
||||
}
|
||||
|
||||
private byte[] _BuildHash(byte[] Key, string Password)
|
||||
{
|
||||
if (Key == null || Password == null)
|
||||
return null;
|
||||
|
||||
byte[] hash = SHA256.ComputeHash(encoder.GetBytes(Password));
|
||||
byte[] serial = new byte[Key.Length + hash.Length];
|
||||
Array.Copy(Key, serial, Key.Length);
|
||||
Array.Copy(hash, 0, serial, Key.Length, hash.Length);
|
||||
|
||||
return SHA256.ComputeHash(serial);
|
||||
}
|
||||
|
||||
private byte[] _Encrypt(byte[] Data)
|
||||
{
|
||||
if (Data == null || (!keySet && encryption))
|
||||
@@ -125,7 +156,7 @@ namespace ClientServerLib
|
||||
|
||||
using (Aes aes = new AesManaged())
|
||||
{
|
||||
aes.Key = dh.Key;
|
||||
aes.Key = key;
|
||||
aes.GenerateIV();
|
||||
|
||||
using (var encryptor = aes.CreateEncryptor(aes.Key, aes.IV))
|
||||
@@ -184,7 +215,7 @@ namespace ClientServerLib
|
||||
|
||||
using (Aes aes = new AesManaged())
|
||||
{
|
||||
aes.Key = dh.Key;
|
||||
aes.Key = key;
|
||||
aes.IV = IV;
|
||||
|
||||
byte[] encrypted = new byte[messageLength - 24];
|
||||
|
||||
@@ -14,6 +14,9 @@ namespace ClientServerLib
|
||||
|
||||
public class CDiscover
|
||||
{
|
||||
public readonly string sTimeout = "Timeout";
|
||||
public readonly string sFinished = "Finished";
|
||||
|
||||
private string _Keyword;
|
||||
private string _BroadcastAddress;
|
||||
private int _Port;
|
||||
@@ -114,7 +117,9 @@ namespace ClientServerLib
|
||||
_DiscoverRunning = false;
|
||||
|
||||
if (!foundSomething)
|
||||
_OnDiscovered("Timeout", "unknown");
|
||||
_OnDiscovered(sTimeout, String.Empty);
|
||||
else
|
||||
_OnDiscovered(sFinished, String.Empty);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,6 +14,7 @@ namespace ClientServerLib
|
||||
private Thread listenThread;
|
||||
private int port;
|
||||
private bool encryption;
|
||||
private string password;
|
||||
private int bufferLength = 8192;
|
||||
private bool running;
|
||||
|
||||
@@ -22,12 +23,13 @@ namespace ClientServerLib
|
||||
private Dictionary<int, CConnection> clients;
|
||||
private Queue<int> ids;
|
||||
|
||||
public CServer(HandleRequest RequestCallback, int Port = 3000, bool Encryption = false)
|
||||
public CServer(HandleRequest RequestCallback, int Port = 3000, string Password = null)
|
||||
{
|
||||
port = Port;
|
||||
running = false;
|
||||
requestCallback = RequestCallback;
|
||||
encryption = Encryption;
|
||||
encryption = Password != null;
|
||||
password = Password;
|
||||
|
||||
clients = new Dictionary<int, CConnection>();
|
||||
ids = new Queue<int>(1000);
|
||||
@@ -92,7 +94,7 @@ namespace ClientServerLib
|
||||
if (client != null)
|
||||
{
|
||||
int id = ids.Dequeue();
|
||||
CConnection connection = new CConnection(client, id, encryption);
|
||||
CConnection connection = new CConnection(client, id, password);
|
||||
|
||||
lock (clients)
|
||||
{
|
||||
@@ -103,10 +105,19 @@ namespace ClientServerLib
|
||||
|
||||
NetworkStream clientStream = client.GetStream();
|
||||
byte[] serverParams = connection.GetKeyParams();
|
||||
clientStream.Write(serverParams, 0, serverParams.Length);
|
||||
clientStream.Flush();
|
||||
|
||||
clientThread.Start(connection);
|
||||
try
|
||||
{
|
||||
clientStream.Write(serverParams, 0, serverParams.Length);
|
||||
clientStream.Flush();
|
||||
}
|
||||
catch
|
||||
{
|
||||
client = null;
|
||||
}
|
||||
|
||||
if (client != null)
|
||||
clientThread.Start(connection);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -162,8 +173,15 @@ namespace ClientServerLib
|
||||
//send message
|
||||
byte[] encrypted = connection.Encrypt(answer);
|
||||
|
||||
clientStream.Write(encrypted, 0, encrypted.Length);
|
||||
clientStream.Flush();
|
||||
try
|
||||
{
|
||||
clientStream.Write(encrypted, 0, encrypted.Length);
|
||||
clientStream.Flush();
|
||||
}
|
||||
catch
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -971,6 +971,9 @@ namespace DiffieHellman
|
||||
|
||||
public override bool Equals(object o)
|
||||
{
|
||||
if (o == null)
|
||||
return false;
|
||||
|
||||
BigInteger bi = (BigInteger)o;
|
||||
|
||||
if (this.dataLength != bi.dataLength)
|
||||
@@ -2965,8 +2968,6 @@ namespace DiffieHellman
|
||||
{
|
||||
data = new uint[0];
|
||||
data = null;
|
||||
GC.Collect();
|
||||
GC.Collect();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -115,10 +115,11 @@ namespace DiffieHellman
|
||||
{
|
||||
// Generate the key.
|
||||
using (BigInteger given = new BigInteger(parts[2], 36))
|
||||
using (BigInteger key = given.ModPow(mine, prime))
|
||||
using (BigInteger key = given.ModPow(mine, prime))
|
||||
{
|
||||
this.key = key.GetBytes();
|
||||
}
|
||||
|
||||
// Generate the response.
|
||||
using (BigInteger send = g.ModPow(mine, prime))
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user