Skip to content

Commit

Permalink
Add NetClientConfiguration properties
Browse files Browse the repository at this point in the history
  • Loading branch information
Filipe GOMES PEIXOTO committed Feb 17, 2018
1 parent 6cf80fb commit b5b2d67
Show file tree
Hide file tree
Showing 8 changed files with 125 additions and 41 deletions.
8 changes: 5 additions & 3 deletions samples/SampleClient/MyClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,11 @@ internal sealed class MyClient : NetClient
/// <param name="host"></param>
/// <param name="port"></param>
/// <param name="bufferSize"></param>
public MyClient(string host, int port, int bufferSize)
: base(host, port, bufferSize)
public MyClient(string host, int port, int bufferSize)
{
this.Configuration.Host = host;
this.Configuration.Port = port;
this.Configuration.BufferSize = bufferSize;
}

/// <summary>
Expand All @@ -33,7 +35,7 @@ public override void HandleMessage(INetPacketStream packet)
/// </summary>
protected override void OnConnected()
{
Console.WriteLine("Connected to {0}", this.Socket.RemoteEndPoint.ToString());
Console.WriteLine("Connected to {0}", this.Socket.RemoteEndPoint);
}

/// <summary>
Expand Down
6 changes: 3 additions & 3 deletions samples/SampleClient/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@

namespace SampleClient
{
class Program
internal class Program
{
static void Main(string[] args)
private static void Main()
{
var client = new MyClient("127.0.0.1", 4444, 512);
client.Connect();
Expand Down Expand Up @@ -39,7 +39,7 @@ static void Main(string[] args)
}

i++;
Thread.Sleep(5);
Thread.Sleep(50);
}
}
catch (Exception e)
Expand Down
4 changes: 2 additions & 2 deletions samples/SampleServer/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

namespace SampleServer
{
class Program
internal class Program
{
static void Main(string[] args)
private static void Main()
{
Console.Title = "Ether.Network Server";

Expand Down
5 changes: 5 additions & 0 deletions src/Ether.Network/Client/INetClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ public interface INetClient : IDisposable
/// Gets the <see cref="INetClient"/> connected state.
/// </summary>
bool IsConnected { get; }

/// <summary>
/// Gets the <see cref="INetClient"/> running state.
/// </summary>
bool IsRunning { get; }

/// <summary>
/// Connects to a remote server.
Expand Down
59 changes: 36 additions & 23 deletions src/Ether.Network/Client/NetClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,7 @@ namespace Ether.Network.Client
public abstract class NetClient : NetUser, INetClient
{
private static readonly IPacketProcessor DefaultPacketProcessor = new NetPacketProcessor();

private readonly IPEndPoint _ipEndPoint;
private readonly SocketAsyncEventArgs _socketReceiveArgs;
private readonly SocketAsyncEventArgs _socketSendArgs;

private readonly AutoResetEvent _autoConnectEvent;
private readonly AutoResetEvent _autoSendEvent;
private readonly BlockingCollection<byte[]> _sendingQueue;
Expand All @@ -32,29 +29,31 @@ public abstract class NetClient : NetUser, INetClient
private readonly CancellationToken _cancelToken;

private bool _isDisposed;
private SocketAsyncEventArgs _socketReceiveArgs;
private SocketAsyncEventArgs _socketSendArgs;

/// <summary>
/// Gets the packet processor.
/// </summary>
protected virtual IPacketProcessor PacketProcessor => DefaultPacketProcessor;

/// <inheritdoc />
public bool IsConnected => this.Socket != null && this.Socket.Connected;

/// <inheritdoc />
public bool IsRunning { get; private set; }

/// <summary>
/// Gets the <see cref="NetClient"/> connected state.
/// Gets the <see cref="NetClient"/> configuration.
/// </summary>
public bool IsConnected => this.Socket != null && this.Socket.Connected;
protected NetClientConfiguration Configuration { get; }

/// <summary>
/// Creates a new <see cref="NetClient"/> instance.
/// </summary>
/// <param name="host">Remote host or ip</param>
/// <param name="port">Remote port</param>
/// <param name="bufferSize">Buffer size</param>
protected NetClient(string host, int port, int bufferSize)
protected NetClient()
{
this.Socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
this._ipEndPoint = NetUtils.CreateIpEndPoint(host, port);
this._socketSendArgs = NetUtils.CreateSocketAsync(this.Socket, this.IO_Completed);
this._socketReceiveArgs = NetUtils.CreateSocketAsync(this, this.IO_Completed, bufferSize);
this.Configuration = new NetClientConfiguration(this);
this._autoConnectEvent = new AutoResetEvent(false);
this._autoSendEvent = new AutoResetEvent(false);
this._sendingQueue = new BlockingCollection<byte[]>();
Expand All @@ -68,11 +67,18 @@ protected NetClient(string host, int port, int bufferSize)
/// <inheritdoc />
public void Connect()
{
if (this.IsRunning)
throw new InvalidOperationException("Client is already running");

if (this.IsConnected)
throw new InvalidOperationException("Client is already connected to remote.");

var connectSocket = NetUtils.CreateSocketAsync(this.Socket, this.IO_Completed);
connectSocket.RemoteEndPoint = this._ipEndPoint;
this.Socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
this._socketSendArgs = NetUtils.CreateSocketAsync(this.Socket, this.IO_Completed);
this._socketReceiveArgs = NetUtils.CreateSocketAsync(this, this.IO_Completed, this.Configuration.BufferSize);

SocketAsyncEventArgs connectSocket = NetUtils.CreateSocketAsync(this.Socket, this.IO_Completed);
connectSocket.RemoteEndPoint = NetUtils.CreateIpEndPoint(this.Configuration.Host, this.Configuration.Port);

if (this.Socket.ConnectAsync(connectSocket))
this._autoConnectEvent.WaitOne();
Expand All @@ -85,7 +91,8 @@ public void Connect()
this._sendingQueueWorker.Start();
this._receivingQueueWorker.Start();
this.Token.Socket = this.Socket;
this.Token.MessageHandler = data => this._receivingQueue.Add(data);
this.Token.MessageHandler = data => this._receivingQueue.Add(data, this._cancelToken);
this.IsRunning = true;

if (!this.Socket.ReceiveAsync(this._socketReceiveArgs))
this.ProcessReceive(this._socketReceiveArgs);
Expand All @@ -100,10 +107,17 @@ public void Disconnect()
this.Socket.Close();
#else
this.Socket.Shutdown(SocketShutdown.Both);
this.Socket.Dispose();
#endif
this.Socket.Dispose();
this.Socket = null;
}

this._socketSendArgs?.Dispose();
this._socketSendArgs = null;
this._socketReceiveArgs?.Dispose();
this._socketReceiveArgs = null;

this.IsRunning = false;
this._cancelTokenSource.Cancel(false);
this.OnDisconnected();
}
Expand All @@ -114,7 +128,7 @@ public override void Send(INetPacketStream packet)
if (!this.IsConnected)
throw new SocketException();

this._sendingQueue.Add(packet.Buffer);
this._sendingQueue.Add(packet.Buffer, this._cancelToken);
}

/// <summary>
Expand Down Expand Up @@ -192,7 +206,7 @@ private void ProcessReceiveQueue()
{
using (INetPacketStream packet = this.PacketProcessor.CreatePacket(packetData))
this.HandleMessage(packet);
});
}, this._cancelToken);
}
catch (Exception e)
{
Expand All @@ -212,9 +226,8 @@ private void ProcessReceive(SocketAsyncEventArgs e)
{
if (e.BytesTransferred <= 0 || !(e.UserToken is NetUser user))
return;

IAsyncUserToken token = user.Token;
SocketAsyncUtils.ReceiveData(e, token, this.PacketProcessor);

SocketAsyncUtils.ReceiveData(e, user.Token, this.PacketProcessor);

if (!user.Socket.ReceiveAsync(e))
this.ProcessReceive(e);
Expand Down
69 changes: 66 additions & 3 deletions src/Ether.Network/Client/NetClientConfiguration.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using Ether.Network.Exceptions;
using Ether.Network.Utils;

namespace Ether.Network.Client
{
Expand All @@ -9,5 +9,68 @@ namespace Ether.Network.Client
/// </summary>
public sealed class NetClientConfiguration
{
private readonly INetClient _client;
private int _port;
private int _bufferSize;
private string _host;

/// <summary>
/// Gets or sets the port.
/// </summary>
public int Port
{
get => this._port;
set => this.SetValue(ref this._port, value);
}

/// <summary>
/// Gets or sets the buffer size.
/// </summary>
public int BufferSize
{
get => this._bufferSize;
set => this.SetValue(ref this._bufferSize, value);
}

/// <summary>
/// Gets or sets the connecting host.
/// </summary>
public string Host
{
get => this._host;
set => this.SetValue(ref this._host, value);
}

/// <summary>
/// Gets the listening address.
/// </summary>
internal IPAddress Address => NetUtils.GetIpAddress(this._host);

/// <summary>
/// Creates a new <see cref="NetClientConfiguration"/> instance.
/// </summary>
/// <param name="client"></param>
internal NetClientConfiguration(INetClient client)
{
this._client = client;
this._bufferSize = 1024;
this._port = 0;
this._host = null;
}

/// <summary>
/// Set the value of a property passed as reference.
/// </summary>
/// <typeparam name="T">Type</typeparam>
/// <param name="container"></param>
/// <param name="value"></param>
private void SetValue<T>(ref T container, T value)
{
if (this._client != null && this._client.IsRunning)
throw new EtherConfigurationException("Cannot change configuration once the client is running.");

if (!Equals(container, value))
container = value;
}
}
}
7 changes: 3 additions & 4 deletions src/Ether.Network/Server/NetServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -306,11 +306,10 @@ private void ProcessReceive(SocketAsyncEventArgs e)
{
if (!(e.UserToken is NetUser connection))
return;

SocketAsyncUtils.ReceiveData(e, connection.Token, this.PacketProcessor);

IAsyncUserToken token = connection.Token;
SocketAsyncUtils.ReceiveData(e, token, this.PacketProcessor);

if (!token.Socket.ReceiveAsync(e))
if (!connection.Socket.ReceiveAsync(e))
this.ProcessReceive(e);
}
else
Expand Down
8 changes: 5 additions & 3 deletions test/Ether.Network.Tests/Contexts/Echo/MyEchoClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,16 @@ public ICollection<string> SendedData
{
this._sendedData.Sort(StringComparer.CurrentCulture);
return this._sendedData;
}
}
}

public bool ConnectedToServer { get; private set; }

public MyEchoClient(string host, int port, int bufferSize)
: base(host, port, bufferSize)
public MyEchoClient(string host, int port, int bufferSize)
{
this.Configuration.Host = host;
this.Configuration.Port = port;
this.Configuration.BufferSize = bufferSize;
this._sendedData = new List<string>();
this._random = new Random();
}
Expand Down

0 comments on commit b5b2d67

Please sign in to comment.