diff --git a/SimpleTCP.Tests/CommTest.cs b/SimpleTCP.Tests/CommTest.cs
index 37040a3..357ab81 100644
--- a/SimpleTCP.Tests/CommTest.cs
+++ b/SimpleTCP.Tests/CommTest.cs
@@ -18,16 +18,18 @@ public class CommTest
public void SimpleCommTest()
{
SimpleTcpServer server = new SimpleTcpServer().Start(8910);
- SimpleTcpClient client = new SimpleTcpClient().Connect(server.GetListeningIPs().FirstOrDefault(ip => ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork).ToString(), 8910);
+ SimpleTcpClient client = new SimpleTcpClient(new SimpleTcpParam{Name = "Alex"}).Connect(server.GetListeningIPs().FirstOrDefault(ip => ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork).ToString(), 8910);
- server.DelimiterDataReceived += (sender, msg) => {
+ server.DelimiterDataReceived += (sender, msg) =>
+ {
_serverRx.Add(msg.MessageString);
string serverReply = Guid.NewGuid().ToString();
msg.ReplyLine(serverReply);
_serverTx.Add(serverReply);
};
- client.DelimiterDataReceived += (sender, msg) => {
+ client.DelimiterDataReceived += (sender, msg) =>
+ {
_clientRx.Add(msg.MessageString);
};
@@ -69,7 +71,7 @@ public void SimpleCommTest()
Assert.IsTrue(true);
-
+
}
}
}
diff --git a/SimpleTCP.Tests/ServerTests.cs b/SimpleTCP.Tests/ServerTests.cs
index feea838..9e6619c 100644
--- a/SimpleTCP.Tests/ServerTests.cs
+++ b/SimpleTCP.Tests/ServerTests.cs
@@ -14,9 +14,10 @@ public class ServerTests : IDisposable
public ServerTests()
{
_server = new SimpleTcpServer().Start(_serverPort);
- }
+ }
+
- public void Dispose()
+ public void Dispose()
{
if (_server.IsStarted)
_server.Stop();
diff --git a/SimpleTCP/MessagemUdp.cs b/SimpleTCP/MessagemUdp.cs
new file mode 100644
index 0000000..fb1841a
--- /dev/null
+++ b/SimpleTCP/MessagemUdp.cs
@@ -0,0 +1,53 @@
+using System.Linq;
+using System.Net.Sockets;
+using System.Text;
+
+namespace SimpleTCP
+{
+ public class MessagemUdp
+ {
+ private UdpClient _udpClient;
+ private Encoding _encoder;
+ private byte _writeLineDelimiter;
+ private bool _autoTrim;
+
+ public byte[] Data { get; }
+
+ public UdpClient TcpClient => _udpClient;
+
+ internal MessagemUdp(byte[] data, UdpClient udpClient, Encoding stringEncoder, byte lineDelimiter, bool autoTrim)
+ {
+ Data = data;
+ _udpClient = udpClient;
+ _encoder = stringEncoder;
+ _writeLineDelimiter = lineDelimiter;
+ _autoTrim = autoTrim;
+ }
+
+ public string MessageString => _autoTrim ? _encoder.GetString(Data).Trim() : _encoder.GetString(Data);
+
+ public void Reply(byte[] data)
+ {
+ _udpClient.Send(data, data.Length);
+ }
+
+ public void Reply(string data)
+ {
+ if (string.IsNullOrEmpty(data)) { return; }
+ Reply(_encoder.GetBytes(data));
+ }
+
+ public void ReplyLine(string data)
+ {
+ if (string.IsNullOrEmpty(data)) { return; }
+ if (data.LastOrDefault() != _writeLineDelimiter)
+ {
+ Reply(data + _encoder.GetString(new[] { _writeLineDelimiter }));
+ }
+ else
+ {
+ Reply(data);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/SimpleTCP/Server/ConnectedClient.cs b/SimpleTCP/Server/ConnectedClient.cs
index c1704a2..65179f4 100644
--- a/SimpleTCP/Server/ConnectedClient.cs
+++ b/SimpleTCP/Server/ConnectedClient.cs
@@ -1,10 +1,5 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Net;
+using System.Net;
using System.Net.Sockets;
-using System.Text;
-using System.Threading.Tasks;
namespace SimpleTCP
{
diff --git a/SimpleTCP/Server/ServerListener.cs b/SimpleTCP/Server/ServerListener.cs
index 7f39d97..f0ad15b 100644
--- a/SimpleTCP/Server/ServerListener.cs
+++ b/SimpleTCP/Server/ServerListener.cs
@@ -1,14 +1,11 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
+using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
-using System.Text;
using System.Threading;
-using System.Threading.Tasks;
namespace SimpleTCP.Server
{
+
internal class ServerListener
{
private TcpListenerEx _listener = null;
@@ -104,7 +101,7 @@ private void RunLoopStep()
if (_listener.Pending())
{
- var newClient = _listener.AcceptTcpClient();
+ var newClient = _listener.AcceptTcpClient();
_connectedClients.Add(newClient);
_parent.NotifyClientConnected(this, newClient);
}
diff --git a/SimpleTCP/Server/TcpListenerEx.cs b/SimpleTCP/Server/TcpListenerEx.cs
index 1811c48..83d4f89 100644
--- a/SimpleTCP/Server/TcpListenerEx.cs
+++ b/SimpleTCP/Server/TcpListenerEx.cs
@@ -19,8 +19,19 @@ public class TcpListenerEx : TcpListener
///
/// An that represents the local endpoint to which to bind the listener . is null.
public TcpListenerEx(IPEndPoint localEP) : base(localEP)
- {
- }
+ {
+ AcceptTcpClient();
+
+
+ }
+
+
+ public TcpClient AcceptTcpClientX()
+ {
+ var a = this.AcceptTcpClient();
+
+ return a;
+ }
///
/// Initializes a new instance of the class that listens for incoming connection attempts on the specified local IP address and port number.
@@ -28,9 +39,9 @@ public TcpListenerEx(IPEndPoint localEP) : base(localEP)
/// An that represents the local IP address. The port on which to listen for incoming connection attempts. is null. is not between and .
public TcpListenerEx(IPAddress localaddr, int port) : base(localaddr, port)
{
- }
+ }
- public new bool Active
+ public new bool Active
{
get { return base.Active; }
}
diff --git a/SimpleTCP/SimpleTCP.csproj b/SimpleTCP/SimpleTCP.csproj
index bc5ae86..9fb5462 100644
--- a/SimpleTCP/SimpleTCP.csproj
+++ b/SimpleTCP/SimpleTCP.csproj
@@ -42,12 +42,15 @@
+
+
+
diff --git a/SimpleTCP/SimpleTcpClient.cs b/SimpleTCP/SimpleTcpClient.cs
index 5c66a93..36fd36c 100644
--- a/SimpleTCP/SimpleTcpClient.cs
+++ b/SimpleTCP/SimpleTcpClient.cs
@@ -3,21 +3,29 @@
using System.Diagnostics;
using System.Linq;
using System.Net.Sockets;
-using System.Text;
using System.Threading;
-using System.Threading.Tasks;
namespace SimpleTCP
{
- public class SimpleTcpClient : IDisposable
+ public class SimpleTcpClient : IDisposable
{
- public SimpleTcpClient()
+ private readonly SimpleTcpParam _param;
+
+ public SimpleTcpClient()
{
StringEncoder = System.Text.Encoding.UTF8;
ReadLoopIntervalMs = 10;
Delimiter = 0x13;
}
+ public SimpleTcpClient(SimpleTcpParam param)
+ {
+ _param = param;
+ StringEncoder = System.Text.Encoding.UTF8;
+ ReadLoopIntervalMs = 10;
+ Delimiter = 0x13;
+ }
+
private Thread _rxThread = null;
private List _queuedMsg = new List();
public byte Delimiter { get; set; }
@@ -38,8 +46,8 @@ public SimpleTcpClient Connect(string hostNameOrIpAddress, int port)
throw new ArgumentNullException("hostNameOrIpAddress");
}
- _client = new TcpClient();
- _client.Connect(hostNameOrIpAddress, port);
+ _client = new TcpClient();
+ _client.Connect(hostNameOrIpAddress, port);
StartRxThread();
@@ -145,7 +153,7 @@ private void NotifyEndTransmissionRx(TcpClient client, byte[] msg)
public void Write(byte[] data)
{
if (_client == null) { throw new Exception("Cannot send data to a null TcpClient (check to see if Connect was called)"); }
- _client.GetStream().Write(data, 0, data.Length);
+ _client.GetStream().Write(data, 0, data.Length);
}
public void Write(string data)
@@ -184,6 +192,24 @@ public Message WriteLineAndGetReply(string data, TimeSpan timeout)
return mReply;
}
+ public Message WriteLineAndGetReply(byte[] data, TimeSpan timeout)
+ {
+ Message mReply = null;
+ this.DataReceived += (s, e) => { mReply = e; };
+ Write(data);
+
+ Stopwatch sw = new Stopwatch();
+ sw.Start();
+
+ while (mReply == null && sw.Elapsed < timeout)
+ {
+ System.Threading.Thread.Sleep(10);
+ }
+
+ return mReply;
+ }
+
+
#region IDisposable Support
private bool disposedValue = false; // To detect redundant calls
diff --git a/SimpleTCP/SimpleTcpParam.cs b/SimpleTCP/SimpleTcpParam.cs
new file mode 100644
index 0000000..bb2333d
--- /dev/null
+++ b/SimpleTCP/SimpleTcpParam.cs
@@ -0,0 +1,7 @@
+namespace SimpleTCP
+{
+ public class SimpleTcpParam
+ {
+ public string Name { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/SimpleTCP/SimpleTcpServer.cs b/SimpleTCP/SimpleTcpServer.cs
index bdafc3e..4f21057 100644
--- a/SimpleTCP/SimpleTcpServer.cs
+++ b/SimpleTCP/SimpleTcpServer.cs
@@ -1,13 +1,10 @@
using System;
-using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
-using System.Text;
using System.Threading;
-using System.Threading.Tasks;
namespace SimpleTCP
{
@@ -26,6 +23,7 @@ public SimpleTcpServer()
public event EventHandler ClientConnected;
public event EventHandler ClientDisconnected;
+
public event EventHandler DelimiterDataReceived;
public event EventHandler DataReceived;
@@ -33,9 +31,9 @@ public IEnumerable GetIPAddresses()
{
List ipAddresses = new List();
- IEnumerable enabledNetInterfaces = NetworkInterface.GetAllNetworkInterfaces()
- .Where(nic => nic.OperationalStatus == OperationalStatus.Up);
- foreach (NetworkInterface netInterface in enabledNetInterfaces)
+ IEnumerable enabledNetInterfaces = NetworkInterface.GetAllNetworkInterfaces()
+ .Where(nic => nic.OperationalStatus == OperationalStatus.Up);
+ foreach (NetworkInterface netInterface in enabledNetInterfaces)
{
IPInterfaceProperties ipProps = netInterface.GetIPProperties();
foreach (UnicastIPAddressInformation addr in ipProps.UnicastAddresses)
@@ -64,10 +62,10 @@ public List GetListeningIPs()
return listenIps.OrderByDescending(ip => RankIpAddress(ip)).ToList();
}
-
+
public void Broadcast(byte[] data)
{
- foreach(var client in _listeners.SelectMany(x => x.ConnectedClients))
+ foreach (var client in _listeners.SelectMany(x => x.ConnectedClients))
{
client.GetStream().Write(data, 0, data.Length);
}
@@ -150,28 +148,28 @@ private static IEnumerable TryGetCurrentNetworkInterfaces()
public SimpleTcpServer Start(int port, bool ignoreNicsWithOccupiedPorts = true)
{
var ipSorted = GetIPAddresses();
- bool anyNicFailed = false;
+ bool anyNicFailed = false;
foreach (var ipAddr in ipSorted)
{
- try
- {
- Start(ipAddr, port);
- }
- catch (SocketException ex)
- {
- DebugInfo(ex.ToString());
- anyNicFailed = true;
- }
+ try
+ {
+ Start(ipAddr, port);
+ }
+ catch (SocketException ex)
+ {
+ DebugInfo(ex.ToString());
+ anyNicFailed = true;
+ }
}
- if (!IsStarted)
- throw new InvalidOperationException("Port was already occupied for all network interfaces");
+ if (!IsStarted)
+ throw new InvalidOperationException("Port was already occupied for all network interfaces");
- if (anyNicFailed && !ignoreNicsWithOccupiedPorts)
- {
- Stop();
- throw new InvalidOperationException("Port was already occupied for one or more network interfaces.");
- }
+ if (anyNicFailed && !ignoreNicsWithOccupiedPorts)
+ {
+ Stop();
+ throw new InvalidOperationException("Port was already occupied for one or more network interfaces.");
+ }
return this;
}
@@ -191,9 +189,9 @@ public SimpleTcpServer Start(int port, AddressFamily addressFamilyFilter)
return this;
}
- public bool IsStarted { get { return _listeners.Any(l => l.Listener.Active); } }
+ public bool IsStarted { get { return _listeners.Any(l => l.Listener.Active); } }
- public SimpleTcpServer Start(IPAddress ipAddress, int port)
+ public SimpleTcpServer Start(IPAddress ipAddress, int port)
{
Server.ServerListener listener = new Server.ServerListener(this, ipAddress, port);
_listeners.Add(listener);
@@ -203,16 +201,18 @@ public SimpleTcpServer Start(IPAddress ipAddress, int port)
public void Stop()
{
- _listeners.All(l => l.QueueStop = true);
- while (_listeners.Any(l => l.Listener.Active)){
- Thread.Sleep(100);
- };
+ _listeners.All(l => l.QueueStop = true);
+ while (_listeners.Any(l => l.Listener.Active))
+ {
+ Thread.Sleep(100);
+ };
_listeners.Clear();
}
public int ConnectedClientsCount
{
- get {
+ get
+ {
return _listeners.Sum(l => l.ConnectedClientsCount);
}
}
@@ -226,6 +226,7 @@ internal void NotifyDelimiterMessageRx(Server.ServerListener listener, TcpClient
}
}
+
internal void NotifyEndTransmissionRx(Server.ServerListener listener, TcpClient client, byte[] msg)
{
if (DataReceived != null)
@@ -251,20 +252,22 @@ internal void NotifyClientDisconnected(Server.ServerListener listener, TcpClient
}
}
- #region Debug logging
-
- [System.Diagnostics.Conditional("DEBUG")]
- void DebugInfo(string format, params object[] args)
- {
- if (_debugInfoTime == null)
- {
- _debugInfoTime = new System.Diagnostics.Stopwatch();
- _debugInfoTime.Start();
- }
- System.Diagnostics.Debug.WriteLine(_debugInfoTime.ElapsedMilliseconds + ": " + format, args);
- }
- System.Diagnostics.Stopwatch _debugInfoTime;
-
- #endregion Debug logging
- }
+
+
+ #region Debug logging
+
+ [System.Diagnostics.Conditional("DEBUG")]
+ void DebugInfo(string format, params object[] args)
+ {
+ if (_debugInfoTime == null)
+ {
+ _debugInfoTime = new System.Diagnostics.Stopwatch();
+ _debugInfoTime.Start();
+ }
+ System.Diagnostics.Debug.WriteLine(_debugInfoTime.ElapsedMilliseconds + ": " + format, args);
+ }
+ System.Diagnostics.Stopwatch _debugInfoTime;
+
+ #endregion Debug logging
+ }
}
diff --git a/SimpleTCP/SimpleUdpClient.cs b/SimpleTCP/SimpleUdpClient.cs
new file mode 100644
index 0000000..cbbe27a
--- /dev/null
+++ b/SimpleTCP/SimpleUdpClient.cs
@@ -0,0 +1,152 @@
+using System;
+using System.Collections.Generic;
+using System.Net;
+using System.Net.Sockets;
+using System.Text;
+using System.Threading;
+
+namespace SimpleTCP
+{
+ public class SimpleUdpClient : IDisposable
+ {
+ private Thread _thread;
+
+ internal bool QueueStop { get; set; }
+
+ public bool Connected { get; private set; }
+
+ public byte Delimiter { get; set; }
+
+ public UdpClient UdpClient { get; private set; }
+
+ public IPEndPoint EndPoint { get; set; }
+
+ public SimpleUdpClient()
+ {
+ Connected = false;
+ Delimiter = 0x13;
+ }
+
+ public event EventHandler DataReceived;
+
+ public void Connect(string hostName, int port)
+ {
+ try
+ {
+ EndPoint = new IPEndPoint(IPAddress.Parse(hostName), port);
+
+ UdpClient = new UdpClient(hostName, port);
+ UdpClient.Connect(hostName, port);
+
+ Connected = UdpClient.Client.Connected;
+
+ if (!Connected) return;
+ if (_thread != null) return;
+
+ _thread = new Thread(ListLoop) { IsBackground = true };
+ _thread.Start();
+
+ }
+ catch (Exception erro)
+ {
+ throw new Exception(erro.Message);
+ }
+ }
+
+ public void Write(byte[] dados)
+ {
+ try
+ {
+ if (UdpClient?.Client == null) return;
+ if (!Connected) return;
+ if (!UdpClient.Client.Connected) return;
+ UdpClient?.Send(dados, dados.Length);
+ }
+ catch (Exception erro)
+ {
+ throw new Exception(erro.Message);
+ }
+ }
+
+ public void Disconnect()
+ {
+ try
+ {
+ QueueStop = false;
+ Connected = false;
+ UdpClient?.Close();
+ }
+ catch (Exception erro)
+ {
+ throw new Exception(erro.Message);
+ }
+ }
+
+ private void ListLoop()
+ {
+ while (!QueueStop)
+ {
+ try
+ {
+ RunLoopStep();
+ }
+ catch
+ {
+ //
+ }
+
+ Thread.Sleep(10);
+ }
+
+ _thread = null;
+ }
+
+ private void RunLoopStep()
+ {
+ if (UdpClient == null) { return; }
+ if (UdpClient.Client == null) { return; }
+ if (UdpClient.Client.Connected == false) { return; }
+ var c = UdpClient;
+
+ var bytesAvailable = c.Available;
+ if (bytesAvailable == 0)
+ {
+ Thread.Sleep(10);
+ return;
+ }
+
+ var bytesReceived = new List();
+
+ var rec = EndPoint;
+
+ while (c.Available > 0 && UdpClient.Client.Connected)
+ {
+ bytesReceived.AddRange(c.Receive(ref rec));
+ }
+
+ if (bytesReceived.Count > 0)
+ {
+ NotifyEndTransmissionRx(c, bytesReceived.ToArray());
+ }
+ }
+
+ private void NotifyEndTransmissionRx(UdpClient client, byte[] msg)
+ {
+ if (DataReceived == null) return;
+ var m = new MessagemUdp(msg, client, Encoding.ASCII, Delimiter, false);
+ DataReceived(this, m);
+ }
+
+ public void Dispose()
+ {
+ QueueStop = false;
+ UdpClient.Close();
+ ((IDisposable)UdpClient)?.Dispose();
+ }
+
+ protected virtual void OnDataReceived(MessagemUdp e)
+ {
+ DataReceived?.Invoke(this, e);
+ }
+ }
+}