}
/// <summary>
- /// Writes the bytes neccessary for a reliable send and stores the send.
+ /// Sends the bytes reliably and stores the send.
/// </summary>
/// <param name="bytes">The byte array to write to.</param>
/// <param name="ackCallback">The callback to make once the packet has been acknowledged.</param>
- void WriteReliableSendHeader(byte[] bytes, Action ackCallback)
+ void ReliableSend(byte sendOption, byte[] data, Action ackCallback)
{
+ byte[] bytes = new byte[data.Length + 3];
+
+ //Add message type
+ bytes[0] = sendOption;
+
+ //Find and reliable ID
lock (reliableDataPacketsSent)
{
//Find an ID not used yet.
//Remember packet
reliableDataPacketsSent.Add(id, packet);
}
+
+ //Copy data into new array
+ Buffer.BlockCopy(data, 0, bytes, bytes.Length - data.Length, data.Length);
+
+ //Write to connection
+ WriteBytesToConnection(bytes);
+
+ Statistics.LogSend(data.Length, bytes.Length);
+ }
+
+ /// <summary>
+ /// Handles a reliable message being received and invokes the data event.
+ /// </summary>
+ /// <param name="buffer">The buffer received.</param>
+ void ReliableReceive(byte[] buffer)
+ {
+ if (ProcessReliableReceive(buffer))
+ InvokeDataReceived(SendOption.Reliable, buffer, 3);
+
+ Statistics.LogReceive(buffer.Length - 3, buffer.Length);
}
/// <summary>
/// </summary>
/// <param name="bytes">The buffer containing the data.</param>
/// <returns>Whether the packet was a new packet or not.</returns>
- bool HandleReliableReceive(byte[] bytes)
+ bool ProcessReliableReceive(byte[] bytes)
{
//Get the ID form the packet
ushort id = (ushort)((bytes[1] << 8) + bytes[2]);
/// Handles acknowledgement packets to us.
/// </summary>
/// <param name="bytes">The buffer containing the data.</param>
- void HandleAcknowledgement(byte[] bytes)
+ void AcknowledgementReceive(byte[] bytes)
{
//Get ID
ushort id = (ushort)((bytes[1] << 8) + bytes[2]);
reliableDataPacketsSent.Remove(id);
}
}
+
+ Statistics.LogReceive(0, bytes.Length);
}
/// <summary>
/// <returns>The bytes that should actually be sent.</returns>
protected void HandleSend(byte[] data, byte sendOption, Action ackCallback = null)
{
- byte[] bytes;
+ //Inform keepalive not to send for a while
+ ResetKeepAliveTimer();
+
switch (sendOption)
{
//Handle reliable header and hellos
case (byte)SendOption.Reliable:
case (byte)SendOptionInternal.Hello:
- bytes = new byte[data.Length + 3];
- WriteReliableSendHeader(bytes, ackCallback);
+ ReliableSend(sendOption, data, ackCallback);
break;
-
+
+ //Treat all else as unreliable
default:
- bytes = new byte[data.Length + 1];
+ UnreliableSend(sendOption, data);
break;
}
-
- //Add message type
- bytes[0] = sendOption;
-
- //Copy data into new array
- Buffer.BlockCopy(data, 0, bytes, bytes.Length - data.Length, data.Length);
-
- //Inform keepalive not to send for a while
- ResetKeepAliveTimer();
-
- //Write to connection
- WriteBytesToConnection(bytes);
-
- Statistics.LogSend(data.Length, bytes.Length);
}
/// <summary>
/// Handles the receiving of data.
/// </summary>
/// <param name="buffer">The buffer containing the bytes received.</param>
- /// <param name="bytesReceived">The number of bytes that were received.</param>
- /// <returns>The bytes of data received.</returns>
- protected byte[] HandleReceive(byte[] buffer, int bytesReceived)
+ protected void HandleReceive(byte[] buffer)
{
//Inform keepalive not to send for a while
ResetKeepAliveTimer();
-
- int headerSize = 1;
+
switch (buffer[0])
{
- //Handle reliable receives
+ //Handle reliable receives
case (byte)SendOption.Reliable:
- headerSize = 3;
-
- if (HandleReliableReceive(buffer) == false)
- return null;
+ ReliableReceive(buffer);
break;
- //Handle acknowledgments
+ //Handle acknowledgments
case (byte)SendOptionInternal.Acknowledgement:
- HandleAcknowledgement(buffer);
-
- return null;
+ AcknowledgementReceive(buffer);
+ break;
- //We need to acknowledge hello messages so just use the same reliable receive
- //method
+ //We need to acknowledge hello messages but dont want to invoke any events!
case (byte)SendOptionInternal.Hello:
- HandleReliableReceive(buffer);
-
- return null;
+ ProcessReliableReceive(buffer);
+ Statistics.LogReceive(buffer.Length - 3, buffer.Length);
+ break;
case (byte)SendOptionInternal.Disconnect:
HandleDisconnect();
+ Statistics.LogReceive(0, buffer.Length);
+ break;
- return null;
+ //Treat everything else as unreliable
+ default:
+ InvokeDataReceived(SendOption.None, buffer, 1);
+ Statistics.LogReceive(buffer.Length - 1, buffer.Length);
+ break;
}
+ }
+
+ void UnreliableSend(byte sendOption, byte[] data)
+ {
+ byte[] bytes = new byte[data.Length + 1];
+
+ //Add message type
+ bytes[0] = sendOption;
+
+ //Copy data into new array
+ Buffer.BlockCopy(data, 0, bytes, bytes.Length - data.Length, data.Length);
- byte[] dataBytes = new byte[bytesReceived - headerSize];
- Buffer.BlockCopy(buffer, headerSize, dataBytes, 0, dataBytes.Length);
+ //Write to connection
+ WriteBytesToConnection(bytes);
- Statistics.LogReceive(dataBytes.Length, bytesReceived);
+ Statistics.LogSend(data.Length, bytes.Length);
+ }
- return dataBytes;
+ /// <summary>
+ /// Helper method to invoke the data received event.
+ /// </summary>
+ /// <param name="sendOption">The send option the message was received with.</param>
+ /// <param name="buffer">The buffer received.</param>
+ /// <param name="dataOffset">The offset of data in the buffer.</param>
+ void InvokeDataReceived(SendOption sendOption, byte[] buffer, int dataOffset)
+ {
+ byte[] dataBytes = new byte[buffer.Length - dataOffset];
+ Buffer.BlockCopy(buffer, dataOffset, dataBytes, 0, dataBytes.Length);
+
+ InvokeDataReceived(dataBytes, sendOption);
}
/// <summary>