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); } } }