Skip to content

Commit

Permalink
V-01-02-00
Browse files Browse the repository at this point in the history
TcpClient: Add DataReceived event. Listen to DataAvailable flag with
thread.
TcpServer: Fixed Connected flag not set properly.
  • Loading branch information
Code-Artist committed Jul 2, 2017
1 parent ffd8cd0 commit ce9b991
Show file tree
Hide file tree
Showing 8 changed files with 100 additions and 21 deletions.
1 change: 1 addition & 0 deletions .hgtags
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
45b6feee55d9a78d4631c564ea3aa4cb2c8f1c4d V-01-00-00
423f9e9883637e04847a204bf774839a975e5058 V-01-01-00
f81c4b9b979b9ece15a1a6ebac9ead59e0b05592 V-01-02-00
31 changes: 29 additions & 2 deletions CodeArtEng.Tcp.Tests/TcpClientTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ public void Setup()
Server.ClientConnected += Server_ClientConnected;
Thread.Sleep(500);
Client = new TcpClient("127.0.0.1", port);
Client.DataReceived += Client_DataReceived;
Client.Connect();
Client.ReadTimeout = 500;
for (int x = 0; x < 10; x++)
Expand All @@ -100,6 +101,7 @@ public void Setup()
Trace.WriteLine("Client Connected");
}


[TestFixtureTearDown]
public void TearDown()
{
Expand Down Expand Up @@ -127,7 +129,7 @@ public void HostName()
{
Assert.AreEqual("127.0.0.1", Client.HostName);
}

[Test]
public void ConnectionPort()
{
Expand All @@ -141,7 +143,7 @@ public void CommunicateWithServer()
TcpDelay();
string returnString = Client.ReadString();
Assert.AreEqual("Server [Message from Client] ACK.", returnString);

}

[Test]
Expand All @@ -157,5 +159,30 @@ public void ReadUntilTimeout()
{
Client.ReadBytes();
}


private bool DataReceiveEventRaised;
private string DataReceived;
private bool ReadDataByEvent = false;
private void Client_DataReceived(object sender, EventArgs e)
{
if (!ReadDataByEvent) return;
DataReceived = Client.ReadString();
DataReceiveEventRaised = true;
ReadDataByEvent = false;
}

[Test]
public void ClientMessageReceivedEvent()
{
DataReceiveEventRaised = false;
DataReceived = string.Empty;
ReadDataByEvent = true;

foreach (TcpServerConnection client in Server.Clients) client.WriteToClient("Testing_ABCD");
Thread.Sleep(100);
Assert.AreEqual(true, DataReceiveEventRaised);
Assert.AreEqual("Testing_ABCD", DataReceived);
}
}
}
10 changes: 0 additions & 10 deletions CodeArtEng.Tcp/CodeArtEng.Tcp.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,6 @@
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug_AllFeatures|AnyCPU'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\Debug_AllFeatures\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DocumentationFile>bin\Debug\CodeArtEng.Tcp.XML</DocumentationFile>
<DebugType>full</DebugType>
<PlatformTarget>AnyCPU</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
Expand Down
4 changes: 2 additions & 2 deletions CodeArtEng.Tcp/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,5 @@
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.1.0.0")]
[assembly: AssemblyFileVersion("1.1.0.0")]
[assembly: AssemblyVersion("1.2.0.0")]
[assembly: AssemblyFileVersion("1.2.0.0")]
55 changes: 52 additions & 3 deletions CodeArtEng.Tcp/TcpClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,10 @@
using System.Diagnostics;
using System.Net.Sockets;
using System.Text;
using System.Threading;

namespace CodeArtEng.Tcp
{
//ToDo: Handle Write Timeout

/// <summary>
/// TCP Client Implementation
/// </summary>
Expand All @@ -20,6 +19,18 @@ public class TcpClient
private int BufferSize;
private bool ConnectState = false;

private bool IncomingDataMonitoringThreadActive = true;
private Thread IncomingDataMonitoring = null;

/// <summary>
/// Occurs when incoming message is detected on input message buffer.
/// </summary>
/// <remarks>Event subscription had to be done before calling <see cref="Connect"/>.
/// A monitoring thread will be launched to watch <see cref="NetworkStream.DataAvailable"/> flag in function <see cref="Connect"/>
/// if and only if DataReceived event is subscribed.
/// </remarks>
public event EventHandler DataReceived;

/// <summary>
/// Occurs when connection is established / disconnected.
/// </summary>
Expand Down Expand Up @@ -89,14 +100,29 @@ public void Connect()
Connected = true;
BufferSize = Client.ReceiveBufferSize;
FixedBuffer = new byte[BufferSize];

if (DataReceived != null)
{
IncomingDataMonitoringThreadActive = true;
IncomingDataMonitoring = new Thread(MonitorIncomingData);
IncomingDataMonitoring.Start();
}
}

/// <summary>
/// Disconnect client from server.
/// </summary>
public void Disconnect()
{
if (Connected) Client.GetStream().Close();
//Gentle close, terminating thread properly
IncomingDataMonitoringThreadActive = false;
Thread.Sleep(10);
IncomingDataMonitoring?.Abort();
IncomingDataMonitoring = null;

TcpStream?.Close();
TcpStream = null;

Client.Close();
Client = new System.Net.Sockets.TcpClient();
Connected = false;
Expand Down Expand Up @@ -187,5 +213,28 @@ public string ReadString()
if (!Connected) Connect();
return ASCIIEncoding.ASCII.GetString(ReadBytes());
}

private void MonitorIncomingData()
{
bool incomingData = TcpStream.DataAvailable;
while (IncomingDataMonitoringThreadActive) //Loop forever
{
if (!incomingData)
{
if (TcpStream.DataAvailable)
{
incomingData = true;
DataReceived?.Invoke(this, null);
}
}
else
{
if (!TcpStream.DataAvailable)
incomingData = false;
}
Thread.Sleep(1);
}

}
}
}
8 changes: 4 additions & 4 deletions CodeArtEng.Tcp/TcpServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -355,7 +355,7 @@ public class TcpServerConnection : IDisposable
/// <summary>
/// Get client connection status.
/// </summary>
public bool Connected { get; private set; }
public bool Connected { get; private set; } = true;

internal TcpServerConnection(TcpServer parent, System.Net.Sockets.TcpClient client)
{
Expand Down Expand Up @@ -423,9 +423,6 @@ private void EndRead(IAsyncResult result)
try
{
int byteRead = TcpStream.EndRead(result);
Debug.WriteLine("Received " + byteRead + " bytes.");
BytesReceived?.Invoke(this, new BytesReceivedEventArgs(this, buffer, byteRead));

if (byteRead == 0)
{
Close();
Expand All @@ -434,6 +431,9 @@ private void EndRead(IAsyncResult result)
}
else
{
Debug.WriteLine("Received " + byteRead + " bytes.");
BytesReceived?.Invoke(this, new BytesReceivedEventArgs(this, buffer, byteRead));

//Build string until delimeter character is detected.
EventHandler<MessageReceivedEventArgs> OnMessageReceived = MessageReceived;
if (OnMessageReceived != null)
Expand Down
Binary file added NuGet Package/CodeArtEng.Tcp.1.2.0.nupkg
Binary file not shown.
12 changes: 12 additions & 0 deletions TcpClientExample/Form1.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,23 @@ public Form1()

Client.HostName = "127.0.0.1";
Client.Port = 10000;
Client.DataReceived += Client_DataReceived;
propertyGrid1.SelectedObject = Client;
btWrite.Enabled = false;
btRead.Enabled = false;
}

private delegate void DelMethod(object sender, BytesReceivedEventArgs e);
private void Client_DataReceived(object sender, EventArgs e)
{
if (InvokeRequired)
{
BeginInvoke(new DelMethod(Client_DataReceived), new object[] { sender, e });
return;
}
txtInput.Text = Client.ReadString();
}

private void btConnect_Click(object sender, EventArgs e)
{
Client.Connect();
Expand Down

0 comments on commit ce9b991

Please sign in to comment.