/// <see cref="HazelException"/> if there is a problem connecting.
/// </remarks>
public abstract void ConnectAsync(byte[] bytes = null, int timeout = 5000);
-
+
+ /// <summary>
+ /// Sends a disconnect message to the end point.
+ /// </summary>
+ public abstract void SendDisconnect();
+
/// <summary>
/// Invokes the DataReceived event.
/// </summary>
/// The <see cref="IPMode">IPMode</see> the client is connected using.
/// </summary>
public IPMode IPMode { get; protected set; }
+
+ public long GetIP4Address()
+ {
+ return ((IPEndPoint)this.RemoteEndPoint).Address.Address;
+ }
}
}
}
}
+ /// <inheritdoc />
+ protected override void WriteBytesToConnectionSync(byte[] bytes, int length)
+ {
+ InvokeDataSentRaw(bytes, length);
+
+ lock (stateLock)
+ {
+ if (State != ConnectionState.Connected && State != ConnectionState.Connecting)
+ throw new InvalidOperationException("Could not send data as this Connection is not connected and is not connecting. Did you disconnect?");
+ }
+
+ try
+ {
+ socket.SendTo(
+ bytes,
+ 0,
+ length,
+ SocketFlags.None,
+ RemoteEndPoint
+ );
+ }
+ catch (ObjectDisposedException)
+ {
+ //User probably called Disconnect in between this method starting and here so report the issue
+ throw new InvalidOperationException("Could not send data as this Connection is not connected. Did you disconnect?");
+ }
+ catch (SocketException e)
+ {
+ HazelException he = new HazelException("Could not send data as a SocketException occured.", e);
+ HandleDisconnect(he);
+ throw he;
+ }
+ }
+
/// <inheritdoc />
public override void Connect(byte[] bytes = null, int timeout = 5000)
{
/// <param name="bytes">The bytes to write.</param>
protected abstract void WriteBytesToConnection(byte[] bytes, int length);
+ /// <summary>
+ /// Writes the given bytes to the connection synchronously.
+ /// </summary>
+ /// <param name="bytes">The bytes to write.</param>
+ protected abstract void WriteBytesToConnectionSync(byte[] bytes, int length);
+
/// <inheritdoc/>
public override void Send(MessageWriter msg)
{
/// <summary>
/// Sends a disconnect message to the end point.
/// </summary>
- protected void SendDisconnect()
+ public override void SendDisconnect()
{
- HandleSend(new byte[0], (byte)UdpSendOption.Disconnect); //TODO Should disconnect wait for an ack?
+ WriteBytesToConnectionSync(new byte[] { (byte)UdpSendOption.Disconnect }, 1);
}
/// <inheritdoc/>
}
}
+ /// <summary>
+ /// Sends data from the listener socket.
+ /// </summary>
+ /// <param name="bytes">The bytes to send.</param>
+ /// <param name="endPoint">The endpoint to send to.</param>
+ internal void SendDataSync(byte[] bytes, int length, EndPoint endPoint)
+ {
+ try
+ {
+ listener.SendTo(
+ bytes,
+ 0,
+ length,
+ SocketFlags.None,
+ endPoint
+ );
+ }
+ catch (SocketException e)
+ {
+ throw new HazelException("Could not send data as a SocketException occured.", e);
+ }
+ catch (ObjectDisposedException)
+ {
+ //Keep alive timer probably ran, ignore
+ return;
+ }
+ }
+
/// <summary>
/// Removes a virtual connection from the list.
/// </summary>
Listener.SendData(bytes, length, RemoteEndPoint);
}
+ /// <inheritdoc />
+ protected override void WriteBytesToConnectionSync(byte[] bytes, int length)
+ {
+ InvokeDataSentRaw(bytes, length);
+
+ lock (stateLock)
+ {
+ if (State != ConnectionState.Connected)
+ throw new InvalidOperationException("Could not send data as this Connection is not connected. Did you disconnect?");
+ }
+
+ Listener.SendDataSync(bytes, length, RemoteEndPoint);
+ }
+
/// <inheritdoc />
/// <remarks>
/// This will always throw a HazelException.