From: Forest Date: Wed, 29 May 2019 04:26:52 +0000 (-0700) Subject: Clean up some stuff, fix some bugs, add a new type of copy to MessageReader, add... X-Git-Tag: 1.0.0~45 X-Git-Url: https://git.deb.at/?a=commitdiff_plain;h=9a55e619d5dec723379239ecd094877bc1d65ffb;p=rhonda%2Fimpostor.hazel.git Clean up some stuff, fix some bugs, add a new type of copy to MessageReader, add a new stat counter. Revise pings so they aren't so chatty over lossy connections. --- diff --git a/Hazel.UnitTests/Hazel.UnitTests.csproj b/Hazel.UnitTests/Hazel.UnitTests.csproj index d29fb81..88f9a73 100644 --- a/Hazel.UnitTests/Hazel.UnitTests.csproj +++ b/Hazel.UnitTests/Hazel.UnitTests.csproj @@ -63,7 +63,7 @@ - + diff --git a/Hazel.UnitTests/MessageReaderTests.cs b/Hazel.UnitTests/MessageReaderTests.cs index 9655ba5..1d5c218 100644 --- a/Hazel.UnitTests/MessageReaderTests.cs +++ b/Hazel.UnitTests/MessageReaderTests.cs @@ -91,6 +91,49 @@ namespace Hazel.UnitTests } + [TestMethod] + public void CopySubMessage() + { + const byte Test1 = 12; + const byte Test2 = 146; + + var msg = new MessageWriter(2048); + msg.StartMessage(1); + + msg.StartMessage(2); + msg.Write(Test1); + msg.Write(Test2); + msg.EndMessage(); + + msg.EndMessage(); + + MessageReader handleMessage = MessageReader.Get(msg.Buffer, 0); + Assert.AreEqual(1, handleMessage.Tag); + + var parentReader = MessageReader.Get(handleMessage); + + handleMessage.Recycle(); + SetZero(handleMessage); + + Assert.AreEqual(1, parentReader.Tag); + + for (int i = 0; i < 5; ++i) + { + + var reader = parentReader.ReadMessage(); + Assert.AreEqual(2, reader.Tag); + Assert.AreEqual(Test1, reader.ReadByte()); + Assert.AreEqual(Test2, reader.ReadByte()); + + var temp = parentReader; + parentReader = MessageReader.CopyMessageIntoParent(reader); + + temp.Recycle(); + SetZero(temp); + SetZero(reader); + } + } + [TestMethod] public void ReadMessageLength() { @@ -127,5 +170,12 @@ namespace Hazel.UnitTests { Assert.IsTrue(MessageWriter.IsLittleEndian()); } + + private void SetZero(MessageReader reader) + { + for (int i = 0; i < reader.Buffer.Length; ++i) + reader.Buffer[i] = 0; + } } + } \ No newline at end of file diff --git a/Hazel.UnitTests/MessageWriterTests.cs b/Hazel.UnitTests/MessageWriterTests.cs index c4096be..b292a5d 100644 --- a/Hazel.UnitTests/MessageWriterTests.cs +++ b/Hazel.UnitTests/MessageWriterTests.cs @@ -145,7 +145,6 @@ namespace Hazel.UnitTests Assert.AreEqual(68000u, reader.ReadPackedUInt32()); } - [TestMethod] public void WritePackedInt() { @@ -154,12 +153,18 @@ namespace Hazel.UnitTests msg.WritePacked(8); msg.WritePacked(250); msg.WritePacked(68000); + msg.WritePacked(60168000); msg.WritePacked(-68000); msg.WritePacked(-250); msg.WritePacked(-8); + + msg.WritePacked(0); + msg.WritePacked(-1); + msg.WritePacked(int.MinValue); + msg.WritePacked(int.MaxValue); msg.EndMessage(); - Assert.AreEqual(3 + 1 + 2 + 3 + 5 + 5 + 5, msg.Position); + Assert.AreEqual(3 + 1 + 2 + 3 + 4 + 5 + 5 + 5 + 1 + 5 + 5 + 5, msg.Position); Assert.AreEqual(msg.Length, msg.Position); MessageReader reader = MessageReader.Get(msg.Buffer, 0); @@ -167,11 +172,16 @@ namespace Hazel.UnitTests Assert.AreEqual(8, reader.ReadPackedInt32()); Assert.AreEqual(250, reader.ReadPackedInt32()); Assert.AreEqual(68000, reader.ReadPackedInt32()); - - + Assert.AreEqual(60168000, reader.ReadPackedInt32()); + Assert.AreEqual(-68000, reader.ReadPackedInt32()); Assert.AreEqual(-250, reader.ReadPackedInt32()); Assert.AreEqual(-8, reader.ReadPackedInt32()); + + Assert.AreEqual(0, reader.ReadPackedInt32()); + Assert.AreEqual(-1, reader.ReadPackedInt32()); + Assert.AreEqual(int.MinValue, reader.ReadPackedInt32()); + Assert.AreEqual(int.MaxValue, reader.ReadPackedInt32()); } [TestMethod] diff --git a/Hazel.UnitTests/StressTests.cs b/Hazel.UnitTests/StressTests.cs new file mode 100644 index 0000000..b670edc --- /dev/null +++ b/Hazel.UnitTests/StressTests.cs @@ -0,0 +1,30 @@ +using System; +using System.Net; +using System.Threading; +using System.Threading.Tasks; +using Hazel.Udp; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace Hazel.UnitTests +{ + [TestClass] + public class StressTests + { + // [TestMethod] + public void StressTestOpeningConnections() + { + // Start a listener in another process, or even better, + // adjust the target IP and start listening on another computer. + var ep = new IPEndPoint(IPAddress.Loopback, 22023); + Parallel.For(0, 10000, + new ParallelOptions { MaxDegreeOfParallelism = 64 }, + (i) => { + + var connection = new UdpClientConnection(ep); + connection.KeepAliveInterval = 50; + + connection.Connect(new byte[5]); + }); + } + } +} diff --git a/Hazel.UnitTests/UdpConnectionTests.cs b/Hazel.UnitTests/UdpConnectionTests.cs index 17515f4..26352b5 100644 --- a/Hazel.UnitTests/UdpConnectionTests.cs +++ b/Hazel.UnitTests/UdpConnectionTests.cs @@ -11,6 +11,69 @@ namespace Hazel.UnitTests [TestClass] public class UdpConnectionTests { + [TestMethod] + public void ServerDisposeDisconnectsTest() + { + IPEndPoint ep = new IPEndPoint(IPAddress.Loopback, 4296); + + bool serverConnected = false; + bool serverDisconnected = false; + bool clientDisconnected = false; + + using (UdpConnectionListener listener = new UdpConnectionListener(new IPEndPoint(IPAddress.Any, 4296))) + using (UdpConnection connection = new UdpClientConnection(ep)) + { + listener.NewConnection += (evt) => + { + serverConnected = true; + evt.Connection.Disconnected += (o, et) => serverDisconnected = true; + }; + connection.Disconnected += (o, evt) => clientDisconnected = true; + + listener.Start(); + connection.Connect(); + + listener.Dispose(); + Thread.Sleep(10); + + Assert.IsTrue(serverConnected); + Assert.IsTrue(clientDisconnected); + Assert.IsFalse(serverDisconnected); + } + } + + [TestMethod] + public void ClientServerDisposeDisconnectsTest() + { + IPEndPoint ep = new IPEndPoint(IPAddress.Loopback, 4296); + + bool serverConnected = false; + bool serverDisconnected = false; + bool clientDisconnected = false; + + using (UdpConnectionListener listener = new UdpConnectionListener(new IPEndPoint(IPAddress.Any, 4296))) + using (UdpConnection connection = new UdpClientConnection(ep)) + { + listener.NewConnection += (evt) => + { + serverConnected = true; + evt.Connection.Disconnected += (o, et) => serverDisconnected = true; + }; + + connection.Disconnected += (o, et) => clientDisconnected = true; + + listener.Start(); + connection.Connect(); + connection.Dispose(); + + Thread.Sleep(10); + + Assert.IsTrue(serverConnected); + Assert.IsTrue(serverDisconnected); + Assert.IsFalse(clientDisconnected); + } + } + /// /// Tests the fields on UdpConnection. /// @@ -208,7 +271,37 @@ namespace Hazel.UnitTests TestHelper.RunClientToServerTest(listener, connection, 10, SendOption.Reliable); } } - + + /// + /// Tests the keepalive functionality from the client, + /// + [TestMethod] + public void PingDisconnectClientTest() + { +#if DEBUG + using (UdpConnectionListener listener = new UdpConnectionListener(new IPEndPoint(IPAddress.Any, 4296))) + using (UdpConnection connection = new UdpClientConnection(new IPEndPoint(IPAddress.Loopback, 4296))) + { + listener.Start(); + + connection.Connect(); + + // After connecting, quietly stop responding to all messages to fake connection loss. + Thread.Sleep(10); + listener.TestDropRate = 1; + + connection.KeepAliveInterval = 100; + + Thread.Sleep(1050); //Enough time for ~10 keep alive packets + + Assert.AreEqual(ConnectionState.NotConnected, connection.State); + Assert.AreEqual(3 * connection.MissingPingsUntilDisconnect + 4, connection.Statistics.TotalBytesSent); // + 4 for connecting overhead + } +#else + Assert.Inconclusive("Only works in DEBUG"); +#endif + } + /// /// Tests the keepalive functionality from the client, /// @@ -225,6 +318,7 @@ namespace Hazel.UnitTests System.Threading.Thread.Sleep(1050); //Enough time for ~10 keep alive packets + Assert.AreEqual(ConnectionState.Connected, connection.State); Assert.IsTrue( connection.Statistics.TotalBytesSent >= 30 && connection.Statistics.TotalBytesSent <= 50, @@ -244,24 +338,15 @@ namespace Hazel.UnitTests using (UdpConnectionListener listener = new UdpConnectionListener(new IPEndPoint(IPAddress.Any, 4296))) using (UdpConnection connection = new UdpClientConnection(new IPEndPoint(IPAddress.Loopback, 4296))) { - listener.NewConnection += delegate(NewConnectionEventArgs args) + UdpConnection client = null; + listener.NewConnection += delegate (NewConnectionEventArgs args) { - ((UdpConnection)args.Connection).KeepAliveInterval = 100; + client = (UdpConnection)args.Connection; + client.KeepAliveInterval = 100; Thread.Sleep(1050); //Enough time for ~10 keep alive packets - try - { - Assert.IsTrue( - args.Connection.Statistics.TotalBytesSent >= 30 && - args.Connection.Statistics.TotalBytesSent <= 50, - "Sent: " + args.Connection.Statistics.TotalBytesSent - ); - } - finally - { - mutex.Set(); - } + mutex.Set(); }; listener.Start(); @@ -269,6 +354,14 @@ namespace Hazel.UnitTests connection.Connect(); mutex.WaitOne(); + + Assert.AreEqual(ConnectionState.Connected, client.State); + + Assert.IsTrue( + client.Statistics.TotalBytesSent >= 27 && + client.Statistics.TotalBytesSent <= 50, + "Sent: " + client.Statistics.TotalBytesSent + ); } } diff --git a/Hazel.UnitTests/UnitTest1.cs b/Hazel.UnitTests/UnitTest1.cs deleted file mode 100644 index 0bc8026..0000000 --- a/Hazel.UnitTests/UnitTest1.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System; -using System.Net; -using System.Threading; -using System.Threading.Tasks; -using Hazel.Udp; -using Microsoft.VisualStudio.TestTools.UnitTesting; - -namespace Hazel.UnitTests -{ - [TestClass] - public class UnitTest1 - { - // [TestMethod] - public void StressTest() - { - var ep = new IPEndPoint(IPAddress.Loopback, 22023); - Parallel.For(0, 10000, - new ParallelOptions { MaxDegreeOfParallelism = 64 }, - (i) => { - - var connection = new UdpClientConnection(ep); - connection.KeepAliveInterval = 50; - - connection.Connect(new byte[5]); - }); - } - } -} diff --git a/Hazel/Connection.cs b/Hazel/Connection.cs index 964e82d..f30d948 100644 --- a/Hazel/Connection.cs +++ b/Hazel/Connection.cs @@ -133,7 +133,7 @@ namespace Hazel /// /// Reset event that is triggered when the connection is marked Connected. /// - ManualResetEvent connectWaitLock = new ManualResetEvent(false); + private ManualResetEvent connectWaitLock = new ManualResetEvent(false); /// /// Constructor that initializes the ConnecitonStatistics object. @@ -291,6 +291,7 @@ namespace Hazel { this.DataReceived = null; this.Disconnected = null; + this.connectWaitLock.Dispose(); } } } diff --git a/Hazel/ConnectionStatistics.cs b/Hazel/ConnectionStatistics.cs index 7e11c20..22a09c2 100644 --- a/Hazel/ConnectionStatistics.cs +++ b/Hazel/ConnectionStatistics.cs @@ -294,6 +294,26 @@ namespace Hazel /// int acknowledgementMessagesReceived; + /// + /// The number of ping messages received. + /// + /// + /// This is the number of hello messages that were received by the , incremented + /// each time that LogHelloReceive is called by the Connection. Messages are counted before the receive event is invoked. + /// + public int PingMessagesReceived + { + get + { + return pingMessagesReceived; + } + } + + /// + /// The number of hello messages received. + /// + int pingMessagesReceived; + /// /// The number of hello messages received. /// @@ -510,6 +530,19 @@ namespace Hazel Interlocked.Add(ref totalBytesReceived, totalLength); } + /// + /// Logs the receiving of a hello data packet in the statistics. + /// + /// The total number of bytes received. + /// + /// This should be called before the received event is invoked so it is up to date for subscribers to that event. + /// + internal void LogPingReceive(int totalLength) + { + Interlocked.Increment(ref pingMessagesReceived); + Interlocked.Add(ref totalBytesReceived, totalLength); + } + /// /// Logs the receiving of a hello data packet in the statistics. /// diff --git a/Hazel/MessageReader.cs b/Hazel/MessageReader.cs index 447c04d..f73fa49 100644 --- a/Hazel/MessageReader.cs +++ b/Hazel/MessageReader.cs @@ -57,6 +57,18 @@ namespace Hazel return output; } + public static MessageReader CopyMessageIntoParent(MessageReader source) + { + var output = MessageReader.GetSized(source.Length + 3); + System.Buffer.BlockCopy(source.Buffer, source.Offset - 3, output.Buffer, 0, source.Length + 3); + + output.Offset = 0; + output.Position = 0; + output.Length = source.Length + 3; + + return output; + } + public static MessageReader Get(MessageReader source) { var output = GetSized(source.Buffer.Length); diff --git a/Hazel/Udp/UdpClientConnection.cs b/Hazel/Udp/UdpClientConnection.cs index 9ada44a..16b7d15 100644 --- a/Hazel/Udp/UdpClientConnection.cs +++ b/Hazel/Udp/UdpClientConnection.cs @@ -41,7 +41,7 @@ namespace Hazel.Udp throw new InvalidOperationException("IPV6 not supported!"); socket = new Socket(AddressFamily.InterNetworkV6, SocketType.Dgram, ProtocolType.Udp); - socket.SetSocketOption(SocketOptionLevel.IPv6, (SocketOptionName)27, false); //TODO these lines shouldn't be needed anymore + socket.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.IPv6Only, false); } reliablePacketTimer = new Timer(ManageReliablePacketsInternal, null, 100, Timeout.Infinite); @@ -90,59 +90,34 @@ namespace Hazel.Udp length, SocketFlags.None, RemoteEndPoint, - delegate (IAsyncResult result) - { - try - { - socket.EndSendTo(result); - } - catch (NullReferenceException) { } - catch (ObjectDisposedException) - { - Disconnect("Could not send as the socket was disposed of."); - } - catch (SocketException) - { - Disconnect("Could not send data as a SocketException occured."); - } - }, - null - ); + HandleSendTo, + null); } + catch (NullReferenceException) { } 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?"); + // Already disposed and disconnected... } - catch (SocketException) + catch (SocketException ex) { - Disconnect("Could not send data as a SocketException occured."); - throw; + Disconnect("Could not send data as a SocketException occured: " + ex.Message, true); } } - protected override void WriteBytesToConnectionSync(byte[] bytes, int length) + private void HandleSendTo(IAsyncResult result) { - DataSentRaw?.Invoke(bytes, length); - try { - socket.SendTo( - bytes, - 0, - length, - SocketFlags.None, - RemoteEndPoint); + socket.EndSendTo(result); } + catch (NullReferenceException) { } 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?"); + // Already disposed and disconnected... } - catch (SocketException) + catch (SocketException ex) { - Disconnect("Could not send data as a SocketException occured."); - throw; + Disconnect("Could not send data as a SocketException occured: " + ex.Message, true); } } @@ -295,7 +270,12 @@ namespace Hazel.Udp { try { - WriteBytesToConnectionSync(DisconnectBytes, 1); + socket.SendTo( + DisconnectBytes, + 0, + 1, + SocketFlags.None, + RemoteEndPoint); } catch { } } @@ -308,8 +288,8 @@ namespace Hazel.Udp if (this._state == ConnectionState.Connected || this._state == ConnectionState.Disconnecting) { - SendDisconnect(); this._state = ConnectionState.NotConnected; + SendDisconnect(); } } diff --git a/Hazel/Udp/UdpConnection.KeepAlive.cs b/Hazel/Udp/UdpConnection.KeepAlive.cs index eccfc98..121ae18 100644 --- a/Hazel/Udp/UdpConnection.KeepAlive.cs +++ b/Hazel/Udp/UdpConnection.KeepAlive.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; using System.Linq; @@ -10,6 +11,30 @@ namespace Hazel.Udp { partial class UdpConnection { + + /// + /// Class to hold packet data + /// + public class PingPacket : IRecyclable + { + private static readonly ObjectPool PacketPool = new ObjectPool(() => new PingPacket()); + + public readonly Stopwatch Stopwatch = new Stopwatch(); + + internal static PingPacket GetObject() + { + return PacketPool.GetObject(); + } + + public void Recycle() + { + Stopwatch.Stop(); + PacketPool.PutObject(this); + } + } + + internal ConcurrentDictionary activePingPackets = new ConcurrentDictionary(); + /// /// The interval from data being received or transmitted to a keepalive packet being sent in milliseconds. /// @@ -33,12 +58,15 @@ namespace Hazel.Udp set { keepAliveInterval = value; - + //Update timer ResetKeepAliveTimer(); } } - int keepAliveInterval = 2000; + int keepAliveInterval = 1500; + + public int MissingPingsUntilDisconnect { get; set; } = 6; + int pingsSinceAck = 0; /// /// The timer creating keepalive pulses. @@ -53,9 +81,16 @@ namespace Hazel.Udp keepAliveTimer = new Timer( (o) => { + if (this.pingsSinceAck >= this.MissingPingsUntilDisconnect) + { + this.Disconnect($"Sent {this.pingsSinceAck} pings that remote has not responded to."); + return; + } + try { - ReliableSend((byte)UdpSendOption.Ping); + SendPing(); + this.pingsSinceAck++; } catch { @@ -68,6 +103,36 @@ namespace Hazel.Udp ); } + // Pings are special, quasi-reliable packets. + // We send them to trigger responses that validate our connection is alive + // They should never be the *cause* of a disconnect. + // Rather, the responses will reset our + void SendPing() + { + ushort id = (ushort)Interlocked.Increment(ref lastIDAllocated); + + byte[] bytes = new byte[3]; + bytes[0] = (byte)UdpSendOption.Ping; + bytes[1] = (byte)(id >> 8); + bytes[2] = (byte)id; + + PingPacket pkt; + if (!this.activePingPackets.TryGetValue(id, out pkt)) + { + pkt = PingPacket.GetObject(); + if (!this.activePingPackets.TryAdd(id, pkt)) + { + throw new Exception("This shouldn't be possible"); + } + } + + pkt.Stopwatch.Restart(); + + WriteBytesToConnection(bytes, bytes.Length); + + Statistics.LogReliableSend(0, bytes.Length); + } + /// /// Resets the keepalive timer to zero. /// @@ -93,4 +158,4 @@ namespace Hazel.Udp } } } -} +} \ No newline at end of file diff --git a/Hazel/Udp/UdpConnection.Reliable.cs b/Hazel/Udp/UdpConnection.Reliable.cs index af8251e..a7e915e 100644 --- a/Hazel/Udp/UdpConnection.Reliable.cs +++ b/Hazel/Udp/UdpConnection.Reliable.cs @@ -228,16 +228,13 @@ namespace Hazel.Udp void AttachReliableID(byte[] buffer, int offset, int sendLength, Action ackCallback = null) { //Find an ID not used yet. - ushort id; - - //Create packet object - Packet packet = Packet.GetObject(); + ushort id = (ushort)Interlocked.Increment(ref lastIDAllocated); - id = (ushort)Interlocked.Increment(ref lastIDAllocated); - - buffer[offset] = (byte)((id >> 8) & 0xFF); + buffer[offset] = (byte)(id >> 8); buffer[offset + 1] = (byte)id; + //Create packet object + Packet packet = Packet.GetObject(); packet.Set( id, this, @@ -300,20 +297,6 @@ namespace Hazel.Udp Statistics.LogReliableSend(length, bytes.Length); } - void ReliableSend(byte sendOption) - { - byte[] bytes = new byte[3]; - bytes[0] = sendOption; - - //Add reliable ID - AttachReliableID(bytes, 1, bytes.Length, null); - - //Write to connection - WriteBytesToConnection(bytes, bytes.Length); - - Statistics.LogReliableSend(0, bytes.Length); - } - /// /// Handles a reliable message being received and invokes the data event. /// @@ -421,6 +404,8 @@ namespace Hazel.Udp /// The buffer containing the data. void AcknowledgementMessageReceive(byte[] bytes) { + this.pingsSinceAck = 0; + //Get ID ushort id = (ushort)((bytes[1] << 8) + bytes[2]); @@ -438,6 +423,16 @@ namespace Hazel.Udp this.AveragePingMs = Math.Max(50, this.AveragePingMs * .7f + rt * .3f); } } + else if (this.activePingPackets.TryRemove(id, out PingPacket pingPkt)) + { + float rt = pingPkt.Stopwatch.ElapsedMilliseconds; + lock (PingLock) + { + this.AveragePingMs = Math.Max(50, this.AveragePingMs * .7f + rt * .3f); + } + + pingPkt.Recycle(); + } Statistics.LogReliableReceive(0, bytes.Length); } diff --git a/Hazel/Udp/UdpConnection.cs b/Hazel/Udp/UdpConnection.cs index ddac37e..503b1c6 100644 --- a/Hazel/Udp/UdpConnection.cs +++ b/Hazel/Udp/UdpConnection.cs @@ -31,12 +31,6 @@ namespace Hazel.Udp /// The bytes to write. protected abstract void WriteBytesToConnection(byte[] bytes, int length); - /// - /// Writes the given bytes to the connection synchronously. - /// - /// The bytes to write. - protected abstract void WriteBytesToConnectionSync(byte[] bytes, int length); - /// public override void Send(MessageWriter msg) { diff --git a/Hazel/Udp/UdpConnectionListener.cs b/Hazel/Udp/UdpConnectionListener.cs index c137776..9a8a3d9 100644 --- a/Hazel/Udp/UdpConnectionListener.cs +++ b/Hazel/Udp/UdpConnectionListener.cs @@ -54,7 +54,7 @@ namespace Hazel.Udp throw new HazelException("IPV6 not supported!"); this.socket = new Socket(AddressFamily.InterNetworkV6, SocketType.Dgram, ProtocolType.Udp); - this.socket.SetSocketOption(SocketOptionLevel.IPv6, (SocketOptionName)27, false); + this.socket.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.IPv6Only, false); } socket.ReceiveBufferSize = BufferSize; @@ -75,8 +75,12 @@ namespace Hazel.Udp var sock = kvp.Value; sock.ManageReliablePackets(); } - - this.reliablePacketTimer.Change(100, Timeout.Infinite); + + try + { + this.reliablePacketTimer.Change(100, Timeout.Infinite); + } + catch { } } /// @@ -300,15 +304,7 @@ namespace Hazel.Udp 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; - } + catch { } } /// diff --git a/Hazel/Udp/UdpServerConnection.cs b/Hazel/Udp/UdpServerConnection.cs index 0cdf03e..4c18a6e 100644 --- a/Hazel/Udp/UdpServerConnection.cs +++ b/Hazel/Udp/UdpServerConnection.cs @@ -45,14 +45,6 @@ namespace Hazel.Udp Listener.SendData(bytes, length, RemoteEndPoint); } - /// - protected override void WriteBytesToConnectionSync(byte[] bytes, int length) - { - // No throw: As an internal interface, I want to try sending bytes whenever the I feel like it. - - Listener.SendDataSync(bytes, length, RemoteEndPoint); - } - /// /// /// This will always throw a HazelException. @@ -79,7 +71,7 @@ namespace Hazel.Udp { try { - WriteBytesToConnection(DisconnectBytes, 1); + Listener.SendDataSync(DisconnectBytes, 1, RemoteEndPoint); } catch { } }