using System;
using System.Net;
namespace Hazel.Udp
{
///
/// Represents a servers's connection to a client that uses the UDP protocol.
///
///
internal sealed class UdpServerConnection : UdpConnection
{
///
/// The connection listener that we use the socket of.
///
///
/// Udp server connections utilize the same socket in the listener for sends/receives, this is the listener that
/// created this connection and is hence the listener this conenction sends and receives via.
///
public UdpConnectionListener Listener { get; private set; }
///
/// Creates a UdpConnection for the virtual connection to the endpoint.
///
/// The listener that created this connection.
/// The endpoint that we are connected to.
/// The IPMode we are connected using.
internal UdpServerConnection(UdpConnectionListener listener, IPEndPoint endPoint, IPMode IPMode, ILogger logger)
: base(logger)
{
this.Listener = listener;
this.EndPoint = endPoint;
this.IPMode = IPMode;
State = ConnectionState.Connected;
this.InitializeKeepAliveTimer();
}
///
protected override void WriteBytesToConnection(byte[] bytes, int length)
{
this.Statistics.LogPacketSend(length);
Listener.SendData(bytes, length, EndPoint);
}
///
///
/// This will always throw a HazelException.
///
public override void Connect(byte[] bytes = null, int timeout = 5000)
{
throw new InvalidOperationException("Cannot manually connect a UdpServerConnection, did you mean to use UdpClientConnection?");
}
///
///
/// This will always throw a HazelException.
///
public override void ConnectAsync(byte[] bytes = null)
{
throw new InvalidOperationException("Cannot manually connect a UdpServerConnection, did you mean to use UdpClientConnection?");
}
///
/// Sends a disconnect message to the end point.
///
protected override bool SendDisconnect(MessageWriter data = null)
{
lock (this)
{
if (this._state != ConnectionState.Connected)
{
return false;
}
this._state = ConnectionState.NotConnected;
}
var bytes = EmptyDisconnectBytes;
if (data != null && data.Length > 0)
{
if (data.SendOption != SendOption.None) throw new ArgumentException("Disconnect messages can only be unreliable.");
bytes = data.ToByteArray(true);
bytes[0] = (byte)UdpSendOption.Disconnect;
}
try
{
Listener.SendDataSync(bytes, bytes.Length, EndPoint);
}
catch { }
return true;
}
protected override void Dispose(bool disposing)
{
Listener.RemoveConnectionTo(EndPoint);
if (disposing)
{
SendDisconnect();
}
base.Dispose(disposing);
}
}
}