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