using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace Hazel
{
///
/// Holds statistics about the traffic through a .
///
///
public class ConnectionStatistics
{
private const int ExpectedMTU = 1200;
///
/// The total number of messages sent.
///
public int MessagesSent
{
get
{
return UnreliableMessagesSent + ReliableMessagesSent + FragmentedMessagesSent + AcknowledgementMessagesSent + HelloMessagesSent;
}
}
private int packetsSent;
public int PacketsSent => this.packetsSent;
private int reliablePacketsAcknowledged;
public int ReliablePacketsAcknowledged => this.reliablePacketsAcknowledged;
///
/// The number of messages sent larger than 576 bytes. This is smaller than most default MTUs.
///
///
/// This is the number of unreliable messages that were sent from the , incremented
/// each time that LogUnreliableSend is called by the Connection. Messages that caused an error are not
/// counted and messages are only counted once all other operations in the send are complete.
///
public int FragmentableMessagesSent
{
get
{
return fragmentableMessagesSent;
}
}
///
/// The number of messages sent larger than 576 bytes.
///
int fragmentableMessagesSent;
///
/// The number of unreliable messages sent.
///
///
/// This is the number of unreliable messages that were sent from the , incremented
/// each time that LogUnreliableSend is called by the Connection. Messages that caused an error are not
/// counted and messages are only counted once all other operations in the send are complete.
///
public int UnreliableMessagesSent
{
get
{
return unreliableMessagesSent;
}
}
///
/// The number of unreliable messages sent.
///
int unreliableMessagesSent;
///
/// The number of reliable messages sent.
///
///
/// This is the number of reliable messages that were sent from the , incremented
/// each time that LogReliableSend is called by the Connection. Messages that caused an error are not
/// counted and messages are only counted once all other operations in the send are complete.
///
public int ReliableMessagesSent
{
get
{
return reliableMessagesSent;
}
}
///
/// The number of unreliable messages sent.
///
int reliableMessagesSent;
///
/// The number of fragmented messages sent.
///
///
/// This is the number of fragmented messages that were sent from the , incremented
/// each time that LogFragmentedSend is called by the Connection. Messages that caused an error are not
/// counted and messages are only counted once all other operations in the send are complete.
///
public int FragmentedMessagesSent
{
get
{
return fragmentedMessagesSent;
}
}
///
/// The number of fragmented messages sent.
///
int fragmentedMessagesSent;
///
/// The number of acknowledgement messages sent.
///
///
/// This is the number of acknowledgements that were sent from the , incremented
/// each time that LogAcknowledgementSend is called by the Connection. Messages that caused an error are not
/// counted and messages are only counted once all other operations in the send are complete.
///
public int AcknowledgementMessagesSent
{
get
{
return acknowledgementMessagesSent;
}
}
///
/// The number of acknowledgement messages sent.
///
int acknowledgementMessagesSent;
///
/// The number of hello messages sent.
///
///
/// This is the number of hello messages that were sent from the , incremented
/// each time that LogHelloSend is called by the Connection. Messages that caused an error are not
/// counted and messages are only counted once all other operations in the send are complete.
///
public int HelloMessagesSent
{
get
{
return helloMessagesSent;
}
}
///
/// The number of hello messages sent.
///
int helloMessagesSent;
///
/// The number of bytes of data sent.
///
///
///
/// This is the number of bytes of data (i.e. user bytes) that were sent from the ,
/// accumulated each time that LogSend is called by the Connection. Messages that caused an error are not
/// counted and messages are only counted once all other operations in the send are complete.
///
///
/// For the number of bytes including protocol bytes see .
///
///
public long DataBytesSent
{
get
{
return Interlocked.Read(ref dataBytesSent);
}
}
///
/// The number of bytes of data sent.
///
long dataBytesSent;
///
/// The number of bytes sent in total.
///
///
///
/// This is the total number of bytes (the data bytes plus protocol bytes) that were sent from the
/// , accumulated each time that LogSend is called by the Connection. Messages that
/// caused an error are not counted and messages are only counted once all other operations in the send are
/// complete.
///
///
/// For the number of data bytes excluding protocol bytes see .
///
///
public long TotalBytesSent
{
get
{
return Interlocked.Read(ref totalBytesSent);
}
}
///
/// The number of bytes sent in total.
///
long totalBytesSent;
///
/// The total number of messages received.
///
public int MessagesReceived
{
get
{
return UnreliableMessagesReceived + ReliableMessagesReceived + FragmentedMessagesReceived + AcknowledgementMessagesReceived + helloMessagesReceived;
}
}
///
/// The number of unreliable messages received.
///
///
/// This is the number of unreliable messages that were received by the , incremented
/// each time that LogUnreliableReceive is called by the Connection. Messages are counted before the receive event is invoked.
///
public int UnreliableMessagesReceived
{
get
{
return unreliableMessagesReceived;
}
}
///
/// The number of unreliable messages received.
///
int unreliableMessagesReceived;
///
/// The number of reliable messages received.
///
///
/// This is the number of reliable messages that were received by the , incremented
/// each time that LogReliableReceive is called by the Connection. Messages are counted before the receive event is invoked.
///
public int ReliableMessagesReceived
{
get
{
return reliableMessagesReceived;
}
}
///
/// The number of reliable messages received.
///
int reliableMessagesReceived;
///
/// The number of fragmented messages received.
///
///
/// This is the number of fragmented messages that were received by the , incremented
/// each time that LogFragmentedReceive is called by the Connection. Messages are counted before the receive event is invoked.
///
public int FragmentedMessagesReceived
{
get
{
return fragmentedMessagesReceived;
}
}
///
/// The number of fragmented messages received.
///
int fragmentedMessagesReceived;
///
/// The number of acknowledgement messages received.
///
///
/// This is the number of acknowledgement messages that were received by the , incremented
/// each time that LogAcknowledgemntReceive is called by the Connection. Messages are counted before the receive event is invoked.
///
public int AcknowledgementMessagesReceived
{
get
{
return acknowledgementMessagesReceived;
}
}
///
/// The number of acknowledgement messages received.
///
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.
///
///
/// 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 HelloMessagesReceived
{
get
{
return helloMessagesReceived;
}
}
///
/// The number of hello messages received.
///
int helloMessagesReceived;
///
/// The number of bytes of data received.
///
///
///
/// This is the number of bytes of data (i.e. user bytes) that were received by the ,
/// accumulated each time that LogReceive is called by the Connection. Messages are counted before the receive
/// event is invoked.
///
///
/// For the number of bytes including protocol bytes see .
///
///
public long DataBytesReceived
{
get
{
return Interlocked.Read(ref dataBytesReceived);
}
}
///
/// The number of bytes of data received.
///
long dataBytesReceived;
///
/// The number of bytes received in total.
///
///
///
/// This is the total number of bytes (the data bytes plus protocol bytes) that were received by the
/// , accumulated each time that LogReceive is called by the Connection. Messages are
/// counted before the receive event is invoked.
///
///
/// For the number of data bytes excluding protocol bytes see .
///
///
public long TotalBytesReceived
{
get
{
return Interlocked.Read(ref totalBytesReceived);
}
}
///
/// The number of bytes received in total.
///
long totalBytesReceived;
public int MessagesResent { get { return messagesResent; } }
int messagesResent;
///
/// Logs the sending of an unreliable data packet in the statistics.
///
/// The number of bytes of data sent.
///
/// This should be called after the data has been sent and should only be called for data that is sent sucessfully.
///
internal void LogUnreliableSend(int dataLength)
{
Interlocked.Increment(ref unreliableMessagesSent);
Interlocked.Add(ref dataBytesSent, dataLength);
}
/// The total number of bytes sent.
internal void LogPacketSend(int totalLength)
{
Interlocked.Increment(ref this.packetsSent);
Interlocked.Add(ref totalBytesSent, totalLength);
if (totalLength > ExpectedMTU)
{
Interlocked.Increment(ref fragmentableMessagesSent);
}
}
///
/// Logs the sending of a reliable data packet in the statistics.
///
/// The number of bytes of data sent.
///
/// This should be called after the data has been sent and should only be called for data that is sent sucessfully.
///
internal void LogReliableSend(int dataLength)
{
Interlocked.Increment(ref reliableMessagesSent);
Interlocked.Add(ref dataBytesSent, dataLength);
}
///
/// Logs the sending of a fragmented data packet in the statistics.
///
/// The number of bytes of data sent.
/// The total number of bytes sent.
///
/// This should be called after the data has been sent and should only be called for data that is sent sucessfully.
///
internal void LogFragmentedSend(int dataLength)
{
Interlocked.Increment(ref fragmentedMessagesSent);
Interlocked.Add(ref dataBytesSent, dataLength);
}
///
/// Logs the sending of a acknowledgement data packet in the statistics.
///
/// The total number of bytes sent.
///
/// This should be called after the data has been sent and should only be called for data that is sent sucessfully.
///
internal void LogAcknowledgementSend()
{
Interlocked.Increment(ref acknowledgementMessagesSent);
}
///
/// Logs the sending of a hellp data packet in the statistics.
///
/// The total number of bytes sent.
///
/// This should be called after the data has been sent and should only be called for data that is sent sucessfully.
///
internal void LogHelloSend()
{
Interlocked.Increment(ref helloMessagesSent);
}
///
/// Logs the receiving of an unreliable data packet in the statistics.
///
/// The number of bytes of data received.
/// 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 LogUnreliableReceive(int dataLength, int totalLength)
{
Interlocked.Increment(ref unreliableMessagesReceived);
Interlocked.Add(ref dataBytesReceived, dataLength);
Interlocked.Add(ref totalBytesReceived, totalLength);
}
///
/// Logs the receiving of a reliable data packet in the statistics.
///
/// The number of bytes of data received.
/// 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 LogReliableReceive(int dataLength, int totalLength)
{
Interlocked.Increment(ref reliableMessagesReceived);
Interlocked.Add(ref dataBytesReceived, dataLength);
Interlocked.Add(ref totalBytesReceived, totalLength);
}
///
/// Logs the receiving of a fragmented data packet in the statistics.
///
/// The number of bytes of data received.
/// 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 LogFragmentedReceive(int dataLength, int totalLength)
{
Interlocked.Increment(ref fragmentedMessagesReceived);
Interlocked.Add(ref dataBytesReceived, dataLength);
Interlocked.Add(ref totalBytesReceived, totalLength);
}
///
/// Logs the receiving of an acknowledgement 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 LogAcknowledgementReceive(int totalLength)
{
Interlocked.Increment(ref acknowledgementMessagesReceived);
Interlocked.Add(ref totalBytesReceived, totalLength);
}
///
/// Logs the unique acknowledgement of a ping or reliable data packet.
///
internal void LogReliablePacketAcknowledged()
{
Interlocked.Increment(ref this.reliablePacketsAcknowledged);
}
///
/// 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.
///
/// 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 LogHelloReceive(int totalLength)
{
Interlocked.Increment(ref helloMessagesReceived);
Interlocked.Add(ref totalBytesReceived, totalLength);
}
internal void LogMessageResent()
{
Interlocked.Increment(ref messagesResent);
}
}
}