]> git.deb.at Git - rhonda/impostor.hazel.git/commitdiff
Add send bytes subset overload for SendBytes
authorForest <chocozilla@gmail.com>
Mon, 16 Jul 2018 20:12:21 +0000 (13:12 -0700)
committerForest <chocozilla@gmail.com>
Mon, 16 Jul 2018 20:12:21 +0000 (13:12 -0700)
Hazel.UnitTests/UdpConnectionTests.cs
Hazel/Connection.cs
Hazel/Udp/UdpClientConnection.cs
Hazel/Udp/UdpConnection.Fragmented.cs
Hazel/Udp/UdpConnection.Reliable.cs
Hazel/Udp/UdpConnection.cs

index 7216fb4cc20d6b9bce5f5d92078321086bfa2b05..2adcd83dc8ad8b006cdb1701d9d64921fe7e15ba 100644 (file)
@@ -53,6 +53,27 @@ namespace Hazel.UnitTests
             }
         }
 
+
+        [TestMethod]
+        public void UdpUnreliableDataSubsetSendTest()
+        {
+            using (UdpConnectionListener listener = new UdpConnectionListener(new NetworkEndPoint(IPAddress.Any, 4296, IPMode.IPv4)))
+            using (UdpConnection connection = new UdpClientConnection(new NetworkEndPoint(IPAddress.Loopback, 4296, IPMode.IPv4)))
+            {
+                listener.Start();
+                listener.NewConnection += delegate (object sender, NewConnectionEventArgs e)
+                {
+                    e.Connection.DataReceived += delegate (object s, DataReceivedEventArgs evt)
+                    {
+                        Assert.IsTrue(Enumerable.SequenceEqual(evt.Bytes, new byte[] { 3, 4 }));
+                    };
+                };
+
+                connection.Connect();
+                connection.SendBytes(new byte[] { 1, 2, 3, 4, 5, 6 }, 2, 2, SendOption.None);
+            }
+        }
+
         /// <summary>
         ///     Tests IPv4 connectivity.
         /// </summary>
@@ -120,7 +141,7 @@ namespace Hazel.UnitTests
             using (UdpConnectionListener listener = new UdpConnectionListener(new NetworkEndPoint(IPAddress.Any, 4296)))
             using (UdpConnection connection = new UdpClientConnection(new NetworkEndPoint(IPAddress.Loopback, 4296)))
             {
-                TestHelper.RunServerToClientTest(listener, connection, (int)(connection.FragmentSize * 9.5), SendOption.FragmentedReliable);
+                TestHelper.RunServerToClientTest(listener, connection, (int)(UdpConnection.FragmentSize * 9.5), SendOption.FragmentedReliable);
             }
         }
 
@@ -159,7 +180,7 @@ namespace Hazel.UnitTests
             using (UdpConnectionListener listener = new UdpConnectionListener(new NetworkEndPoint(IPAddress.Any, 4296)))
             using (UdpConnection connection = new UdpClientConnection(new NetworkEndPoint(IPAddress.Loopback, 4296)))
             {
-                TestHelper.RunClientToServerTest(listener, connection, (int)(connection.FragmentSize * 9.5), SendOption.FragmentedReliable);
+                TestHelper.RunClientToServerTest(listener, connection, (int)(UdpConnection.FragmentSize * 9.5), SendOption.FragmentedReliable);
             }
         }
 
index 7bc9d57fb334efd14317c383c0591ceabcc136aa..12c35dd9a96319cfb8abdf1b3594eaee5bfa9dee 100644 (file)
@@ -158,6 +158,23 @@ namespace Hazel
         /// </remarks>
         public abstract void SendBytes(byte[] bytes, SendOption sendOption = SendOption.None);
 
+        /// <summary>
+        ///     Sends a number of bytes to the end point of the connection using the specified <see cref="SendOption"/>.
+        /// </summary>
+        /// <param name="bytes">The bytes of the message to send.</param>
+        /// <param name="offset"></param>
+        /// <param name="length"></param>
+        /// <param name="sendOption">The option specifying how the message should be sent.</param>
+        /// <remarks>
+        ///     <include file="DocInclude/common.xml" path="docs/item[@name='Connection_SendBytes_General']/*" />
+        ///     <para>
+        ///         The sendOptions parameter is only a request to use those options and the actual method used to send the
+        ///         data is up to the implementation. There are circumstances where this parameter may be ignored but in 
+        ///         general any implementer should aim to always follow the user's request.
+        ///     </para>
+        /// </remarks>
+        public abstract void SendBytes(byte[] bytes, int offset, int length, SendOption sendOption = SendOption.None);
+
         /// <summary>
         ///     Connects the connection to a server and begins listening.
         /// </summary>
index 0291c025f394a2c578985357d830e15bb16847e3..2f5dfa12de904a3612ba078015c801ae209974df 100644 (file)
@@ -202,7 +202,7 @@ namespace Hazel.Udp
             //Copy data to new array
             byte[] bytes = new byte[bytesReceived];
             Buffer.BlockCopy(dataBuffer, 0, bytes, 0, bytesReceived);
-
+            
             //Begin receiving again
             try
             {
index 463fbef7ea04a0d89e787bc86356557c17e6b3fb..209eb8d61d246525e8728b90776ff142f3aaac0a 100644 (file)
@@ -10,8 +10,7 @@ namespace Hazel.Udp
         /// <summary>
         ///     The amount of data that can be put into a fragment.
         /// </summary>
-        public int FragmentSize { get { return fragmentSize; } }
-        int fragmentSize = 65507 - 1 - 2 - 2 - 2;
+        public const int FragmentSize = 65507 - 1 - 2 - 2 - 2;
 
         /// <summary>
         ///     The last fragmented message ID that was written.
index 0b3cdd5408950f39a6672bfbe2d24835125f55f3..fd40398876f3cd837d0ed7028e950cb62a704216 100644 (file)
@@ -247,25 +247,39 @@ namespace Hazel.Udp
         /// <summary>
         ///     Sends the bytes reliably and stores the send.
         /// </summary>
-        /// <param name="bytes">The byte array to write to.</param>
+        /// <param name="sendOption"></param>
+        /// <param name="data">The byte array to write to.</param>
         /// <param name="ackCallback">The callback to make once the packet has been acknowledged.</param>
         void ReliableSend(byte sendOption, byte[] data, Action ackCallback = null)
         {
-            byte[] bytes = new byte[data.Length + 3];
+            this.ReliableSend(sendOption, data, 0, data.Length, ackCallback);
+        }
+
+        /// <summary>
+        ///     Sends the bytes reliably and stores the send.
+        /// </summary>
+        /// <param name="sendOption"></param>
+        /// <param name="data">The byte array to write to.</param>
+        /// <param name="offset"></param>
+        /// <param name="length"></param>
+        /// <param name="ackCallback">The callback to make once the packet has been acknowledged.</param>
+        void ReliableSend(byte sendOption, byte[] data, int offset, int length, Action ackCallback = null)
+        {
+            byte[] bytes = new byte[length + 3];
 
             //Add message type
             bytes[0] = sendOption;
 
             //Add reliable ID
             AttachReliableID(bytes, 1, ackCallback);
-            
+
             //Copy data into new array
-            Buffer.BlockCopy(data, 0, bytes, bytes.Length - data.Length, data.Length);
+            Buffer.BlockCopy(data, offset, bytes, bytes.Length - length, length);
 
             //Write to connection
             WriteBytesToConnection(bytes);
 
-            Statistics.LogReliableSend(data.Length, bytes.Length);
+            Statistics.LogReliableSend(length, bytes.Length);
         }
 
         /// <summary>
index 6f97d2d5e32ab03e0567d8db123c05f3df37a526..7f4c22d4a8dc694f2e954037df62496b24847218 100644 (file)
@@ -1,5 +1,6 @@
 using System;
 using System.Collections.Generic;
+using System.IO;
 using System.Linq;
 using System.Net;
 using System.Net.Sockets;
@@ -47,6 +48,50 @@ namespace Hazel.Udp
             HandleSend(bytes, (byte)sendOption);
         }
 
+        /// <summary>
+        ///     Sends a number of bytes to the end point of the connection using the specified <see cref="SendOption"/>.
+        /// </summary>
+        /// <param name="bytes">The bytes of the message to send.</param>
+        /// <param name="offset"></param>
+        /// <param name="length"></param>
+        /// <param name="sendOption">The option specifying how the message should be sent.</param>
+        /// <remarks>
+        ///     <include file="DocInclude/common.xml" path="docs/item[@name='Connection_SendBytes_General']/*" />
+        ///     <para>
+        ///         The sendOptions parameter is only a request to use those options and the actual method used to send the
+        ///         data is up to the implementation. There are circumstances where this parameter may be ignored but in 
+        ///         general any implementer should aim to always follow the user's request.
+        ///     </para>
+        /// </remarks>
+        public override void SendBytes(byte[] bytes, int offset, int length, SendOption sendOption = SendOption.None)
+        {
+            //Early check
+            if (State != ConnectionState.Connected)
+                throw new InvalidOperationException("Could not send data as this Connection is not connected. Did you disconnect?");
+
+
+            //Inform keepalive not to send for a while
+            ResetKeepAliveTimer();
+
+            switch (sendOption)
+            {
+                //Handle reliable header and hellos
+                case SendOption.Reliable:
+                    ReliableSend((byte)sendOption, bytes, offset, length);
+                    break;
+
+                case SendOption.FragmentedReliable:
+                    throw new NotImplementedException();
+                    // FragmentedSend(data);
+                    // break;
+
+                //Treat all else as unreliable
+                default:
+                    UnreliableSend((byte)sendOption, bytes, offset, length);
+                    break;
+            }
+        }
+
         /// <summary>
         ///     Handles the reliable/fragmented sending from this connection.
         /// </summary>
@@ -73,7 +118,7 @@ namespace Hazel.Udp
                 
                 //Treat all else as unreliable
                 default:
-                    UnreliableSend(data, sendOption);
+                    UnreliableSend(sendOption, data);
                     break;
             }
         }
@@ -126,25 +171,37 @@ namespace Hazel.Udp
             }
         }
 
+        /// <summary>
+        ///     Sends bytes using the unreliable UDP protocol.
+        /// </summary>
+        /// <param name="sendOption">The SendOption to attach.</param>
+        /// <param name="data">The data.</param>
+        void UnreliableSend(byte sendOption, byte[] data)
+        {
+            this.UnreliableSend(sendOption, data, 0, data.Length);
+        }
+
         /// <summary>
         ///     Sends bytes using the unreliable UDP protocol.
         /// </summary>
         /// <param name="data">The data.</param>
         /// <param name="sendOption">The SendOption to attach.</param>
-        void UnreliableSend(byte[] data, byte sendOption)
+        /// <param name="offset"></param>
+        /// <param name="length"></param>
+        void UnreliableSend(byte sendOption, byte[] data, int offset, int length)
         {
-            byte[] bytes = new byte[data.Length + 1];
+            byte[] bytes = new byte[length + 1];
 
             //Add message type
             bytes[0] = sendOption;
-            
+
             //Copy data into new array
-            Buffer.BlockCopy(data, 0, bytes, bytes.Length - data.Length, data.Length);
+            Buffer.BlockCopy(data, offset, bytes, bytes.Length - length, length);
 
             //Write to connection
             WriteBytesToConnection(bytes);
 
-            Statistics.LogUnreliableSend(data.Length, bytes.Length);
+            Statistics.LogUnreliableSend(length, bytes.Length);
         }
 
         /// <summary>