Skip to content

Commit

Permalink
NuGet v2.0, breaking changes, thanks to @MrMikeJJ for his extensive c…
Browse files Browse the repository at this point in the history
…ommits and pull requests!
  • Loading branch information
Joel Christner committed Sep 5, 2019
1 parent 22fa490 commit 34eb54b
Show file tree
Hide file tree
Showing 20 changed files with 681 additions and 712 deletions.
45 changes: 22 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,12 @@

A simple C# async TCP server and client with integrated framing for reliable transmission and receipt of data.

## New in v1.3.x
## New in v2.x

- Numerous fixes to authentication using preshared keys
- Authentication callbacks in the client to handle authentication events
- ```AuthenticationRequested``` - authentication requested by the server, return the preshared key string (16 bytes)
- ```AuthenticationSucceeded``` - authentication has succeeded, return true
- ```AuthenticationFailure``` - authentication has failed, return true
- Support for sending and receiving larger messages by using streams instead of byte arrays
- Refer to ```TestServerStream``` and ```TestClientStream``` for a reference implementation. You must set ```client.ReadDataStream = false``` and ```server.ReadDataStream = false``` and use the ```StreamReceived``` callback instead of ```MessageReceived```
- Async Task-based callbacks
- Configurable connect timeout in WatsonTcpClient
- Clients can now connect via SSL without a certificate
- Big thanks to @MrMikeJJ for his extensive commits and pull requests

## Test Applications

Expand Down Expand Up @@ -99,24 +96,21 @@ static void Main(string[] args)
}
}
static bool ClientConnected(string ipPort)
static async Task ClientConnected(string ipPort)
{
Console.WriteLine("Client connected: " + ipPort);
return true;
}
static bool ClientDisconnected(string ipPort)
static async Task ClientDisconnected(string ipPort)
{
Console.WriteLine("Client disconnected: " + ipPort);
return true;
}
static bool MessageReceived(string ipPort, byte[] data)
static async Task MessageReceived(string ipPort, byte[] data)
{
string msg = "";
if (data != null && data.Length > 0) msg = Encoding.UTF8.GetString(data);
Console.WriteLine("Message received from " + ipPort + ": " + msg);
return true;
}
```

Expand Down Expand Up @@ -164,22 +158,19 @@ static void Main(string[] args)
}
}
static bool MessageReceived(byte[] data)
static async Task MessageReceived(byte[] data)
{
Console.WriteLine("Message from server: " + Encoding.UTF8.GetString(data));
return true;
}
static bool ServerConnected()
static async Task ServerConnected()
{
Console.WriteLine("Server connected");
return true;
}
static bool ServerDisconnected()
static async Task ServerDisconnected()
{
Console.WriteLine("Server disconnected");
return true;
}
```

Expand Down Expand Up @@ -218,7 +209,7 @@ server.StreamReceived = StreamReceived;
server.ReadDataStream = false;
server.Start();
static bool StreamReceived(string ipPort, long contentLength, Stream stream)
static async Task StreamReceived(string ipPort, long contentLength, Stream stream)
{
// read contentLength bytes from the stream from client ipPort and process
return true;
Expand All @@ -232,15 +223,23 @@ client.StreamReceived = StreamReceived;
client.ReadDataStream = false;
client.Start();
static bool StreamReceived(long contentLength, Stream stream)
static async Task StreamReceived(long contentLength, Stream stream)
{
// read contentLength bytes from the stream and process
return true;
}
```

## Version History

v1.3.x
- Numerous fixes to authentication using preshared keys
- Authentication callbacks in the client to handle authentication events
- ```AuthenticationRequested``` - authentication requested by the server, return the preshared key string (16 bytes)
- ```AuthenticationSucceeded``` - authentication has succeeded, return true
- ```AuthenticationFailure``` - authentication has failed, return true
- Support for sending and receiving larger messages by using streams instead of byte arrays
- Refer to ```TestServerStream``` and ```TestClientStream``` for a reference implementation. You must set ```client.ReadDataStream = false``` and ```server.ReadDataStream = false``` and use the ```StreamReceived``` callback instead of ```MessageReceived```

v1.2.x
- Breaking changes for assigning callbacks, various server/client class variables, and starting them
- Consolidated SSL and non-SSL clients and servers into single classes for each
Expand Down
116 changes: 73 additions & 43 deletions TestClient/Program.cs
Original file line number Diff line number Diff line change
@@ -1,27 +1,24 @@
using System;
using System.Text;
using System.Threading.Tasks;
using WatsonTcp;

namespace TestClient
{
class TestClient
internal class TestClient
{
static string serverIp = "";
static int serverPort = 0;
static bool useSsl = false;
static string certFile = "";
static string certPass = "";
static bool acceptInvalidCerts = true;
static bool mutualAuthentication = true;
static WatsonTcpClient client = null;
static string presharedKey = null;

static void Main(string[] args)
private static string serverIp = "";
private static int serverPort = 0;
private static bool useSsl = false;
private static string certFile = "";
private static string certPass = "";
private static bool acceptInvalidCerts = true;
private static bool mutualAuthentication = true;
private static WatsonTcpClient client = null;
private static string presharedKey = null;

private static void Main(string[] args)
{
serverIp = Common.InputString("Server IP:", "127.0.0.1", false);
serverPort = Common.InputInteger("Server port:", 9000, true, false);
useSsl = Common.InputBoolean("Use SSL:", false);

InitializeClient();

bool runForever = true;
Expand Down Expand Up @@ -68,7 +65,7 @@ static void Main(string[] args)
break;
}

client.Send(Encoding.UTF8.GetBytes(userInput));
if (!client.Send(Encoding.UTF8.GetBytes(userInput))) Console.WriteLine("Failed");
break;

case "sendasync":
Expand All @@ -79,7 +76,7 @@ static void Main(string[] args)
break;
}

bool success = client.SendAsync(Encoding.UTF8.GetBytes(userInput)).Result;
if (!client.SendAsync(Encoding.UTF8.GetBytes(userInput)).Result) Console.WriteLine("Failed");
break;

case "status":
Expand Down Expand Up @@ -109,17 +106,12 @@ static void Main(string[] args)
client.ServerConnected = ServerConnected;
client.ServerDisconnected = ServerDisconnected;
client.MessageReceived = MessageReceived;
client.Start();
client.Start();
}
break;

case "reconnect":
if (client != null) client.Dispose();
client = new WatsonTcpClient(serverIp, serverPort);
client.ServerConnected = ServerConnected;
client.ServerDisconnected = ServerDisconnected;
client.MessageReceived = MessageReceived;
client.Start();
ConnectClient();
break;

case "psk":
Expand All @@ -141,19 +133,47 @@ static void Main(string[] args)
}
}

static void InitializeClient()
{
private static void InitializeClient()
{
serverIp = Common.InputString("Server IP:", "127.0.0.1", false);
serverPort = Common.InputInteger("Server port:", 9000, true, false);
useSsl = Common.InputBoolean("Use SSL:", false);

if (!useSsl)
{
client = new WatsonTcpClient(serverIp, serverPort);
}
else
{
certFile = Common.InputString("Certificate file:", "test.pfx", false);
certPass = Common.InputString("Certificate password:", "password", false);
bool supplyCert = Common.InputBoolean("Supply SSL certificate:", false);

if (supplyCert)
{
certFile = Common.InputString("Certificate file:", "test.pfx", false);
certPass = Common.InputString("Certificate password:", "password", false);
}

acceptInvalidCerts = Common.InputBoolean("Accept Invalid Certs:", true);
mutualAuthentication = Common.InputBoolean("Mutually authenticate:", true);
mutualAuthentication = Common.InputBoolean("Mutually authenticate:", false);

client = new WatsonTcpClient(serverIp, serverPort, certFile, certPass);
client.AcceptInvalidCertificates = acceptInvalidCerts;
client.MutuallyAuthenticate = mutualAuthentication;
}

ConnectClient();
}

private static void ConnectClient()
{
if (client != null) client.Dispose();

if (!useSsl)
{
client = new WatsonTcpClient(serverIp, serverPort);
}
else
{
client = new WatsonTcpClient(serverIp, serverPort, certFile, certPass);
client.AcceptInvalidCertificates = acceptInvalidCerts;
client.MutuallyAuthenticate = mutualAuthentication;
Expand All @@ -168,10 +188,10 @@ static void InitializeClient()
client.ReadDataStream = true;
client.ReadStreamBufferSize = 65536;
// client.Debug = true;
client.Start();
client.Start();
}

static string AuthenticationRequested()
private static string AuthenticationRequested()
{
Console.WriteLine("");
Console.WriteLine("");
Expand All @@ -181,34 +201,44 @@ static string AuthenticationRequested()
return presharedKey;
}

static bool AuthenticationSucceeded()
#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously

private static async Task AuthenticationSucceeded()
#pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously
{
Console.WriteLine("Authentication succeeded");
return true;
}

static bool AuthenticationFailure()
#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously

private static async Task AuthenticationFailure()
#pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously
{
Console.WriteLine("Authentication failed");
return true;
}

static bool MessageReceived(byte[] data)
#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously

private static async Task MessageReceived(byte[] data)
#pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously
{
Console.WriteLine("Message from server: " + Encoding.UTF8.GetString(data));
return true;
}

static bool ServerConnected()
#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously

private static async Task ServerConnected()
#pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously
{
Console.WriteLine("Server connected");
return true;
}

static bool ServerDisconnected()
#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously

private static async Task ServerDisconnected()
#pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously
{
Console.WriteLine("Server disconnected");
return true;
}
}
}
}
Loading

0 comments on commit 34eb54b

Please sign in to comment.