MsgChannel.h 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. /*
  2. ===========================================================================
  3. Doom 3 GPL Source Code
  4. Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
  5. This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
  6. Doom 3 Source Code is free software: you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation, either version 3 of the License, or
  9. (at your option) any later version.
  10. Doom 3 Source Code is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
  16. In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
  17. If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
  18. ===========================================================================
  19. */
  20. #ifndef __MSGCHANNEL_H__
  21. #define __MSGCHANNEL_H__
  22. /*
  23. ===============================================================================
  24. Network channel.
  25. Handles message fragmentation and out of order / duplicate suppression.
  26. Unreliable messages are not garrenteed to arrive but when they do, they
  27. arrive in order and without duplicates. Reliable messages always arrive,
  28. and they also arrive in order without duplicates. Reliable messages piggy
  29. back on unreliable messages. As such an unreliable message stream is
  30. required for the reliable messages to be delivered.
  31. ===============================================================================
  32. */
  33. #define MAX_MESSAGE_SIZE 16384 // max length of a message, which may
  34. // be fragmented into multiple packets
  35. #define CONNECTIONLESS_MESSAGE_ID -1 // id for connectionless messages
  36. #define CONNECTIONLESS_MESSAGE_ID_MASK 0x7FFF // value to mask away connectionless message id
  37. #define MAX_MSG_QUEUE_SIZE 16384 // must be a power of 2
  38. class idMsgQueue {
  39. public:
  40. idMsgQueue();
  41. void Init( int sequence );
  42. bool Add( const byte *data, const int size );
  43. bool Get( byte *data, int &size );
  44. int GetTotalSize( void ) const;
  45. int GetSpaceLeft( void ) const;
  46. int GetFirst( void ) const { return first; }
  47. int GetLast( void ) const { return last; }
  48. void CopyToBuffer( byte *buf ) const;
  49. private:
  50. byte buffer[MAX_MSG_QUEUE_SIZE];
  51. int first; // sequence number of first message in queue
  52. int last; // sequence number of last message in queue
  53. int startIndex; // index pointing to the first byte of the first message
  54. int endIndex; // index pointing to the first byte after the last message
  55. void WriteByte( byte b );
  56. byte ReadByte( void );
  57. void WriteShort( int s );
  58. int ReadShort( void );
  59. void WriteLong( int l );
  60. int ReadLong( void );
  61. void WriteData( const byte *data, const int size );
  62. void ReadData( byte *data, const int size );
  63. };
  64. class idMsgChannel {
  65. public:
  66. idMsgChannel();
  67. void Init( const netadr_t adr, const int id );
  68. void Shutdown( void );
  69. void ResetRate( void );
  70. // Sets the maximum outgoing rate.
  71. void SetMaxOutgoingRate( int rate ) { maxRate = rate; }
  72. // Gets the maximum outgoing rate.
  73. int GetMaxOutgoingRate( void ) { return maxRate; }
  74. // Returns the address of the entity at the other side of the channel.
  75. netadr_t GetRemoteAddress( void ) const { return remoteAddress; }
  76. // Returns the average outgoing rate over the last second.
  77. int GetOutgoingRate( void ) const { return outgoingRateBytes; }
  78. // Returns the average incoming rate over the last second.
  79. int GetIncomingRate( void ) const { return incomingRateBytes; }
  80. // Returns the average outgoing compression ratio over the last second.
  81. float GetOutgoingCompression( void ) const { return outgoingCompression; }
  82. // Returns the average incoming compression ratio over the last second.
  83. float GetIncomingCompression( void ) const { return incomingCompression; }
  84. // Returns the average incoming packet loss over the last 5 seconds.
  85. float GetIncomingPacketLoss( void ) const;
  86. // Returns true if the channel is ready to send new data based on the maximum rate.
  87. bool ReadyToSend( const int time ) const;
  88. // Sends an unreliable message, in order and without duplicates.
  89. int SendMessage( idPort &port, const int time, const idBitMsg &msg );
  90. // Sends the next fragment if the last message was too large to send at once.
  91. void SendNextFragment( idPort &port, const int time );
  92. // Returns true if there are unsent fragments left.
  93. bool UnsentFragmentsLeft( void ) const { return unsentFragments; }
  94. // Processes the incoming message. Returns true when a complete message
  95. // is ready for further processing. In that case the read pointer of msg
  96. // points to the first byte ready for reading, and sequence is set to
  97. // the sequence number of the message.
  98. bool Process( const netadr_t from, int time, idBitMsg &msg, int &sequence );
  99. // Sends a reliable message, in order and without duplicates.
  100. bool SendReliableMessage( const idBitMsg &msg );
  101. // Returns true if a new reliable message is available and stores the message.
  102. bool GetReliableMessage( idBitMsg &msg );
  103. // Removes any pending outgoing or incoming reliable messages.
  104. void ClearReliableMessages( void );
  105. private:
  106. netadr_t remoteAddress; // address of remote host
  107. int id; // our identification used instead of port number
  108. int maxRate; // maximum number of bytes that may go out per second
  109. idCompressor * compressor; // compressor used for data compression
  110. // variables to control the outgoing rate
  111. int lastSendTime; // last time data was sent out
  112. int lastDataBytes; // bytes left to send at last send time
  113. // variables to keep track of the rate
  114. int outgoingRateTime;
  115. int outgoingRateBytes;
  116. int incomingRateTime;
  117. int incomingRateBytes;
  118. // variables to keep track of the compression ratio
  119. float outgoingCompression;
  120. float incomingCompression;
  121. // variables to keep track of the incoming packet loss
  122. float incomingReceivedPackets;
  123. float incomingDroppedPackets;
  124. int incomingPacketLossTime;
  125. // sequencing variables
  126. int outgoingSequence;
  127. int incomingSequence;
  128. // outgoing fragment buffer
  129. bool unsentFragments;
  130. int unsentFragmentStart;
  131. byte unsentBuffer[MAX_MESSAGE_SIZE];
  132. idBitMsg unsentMsg;
  133. // incoming fragment assembly buffer
  134. int fragmentSequence;
  135. int fragmentLength;
  136. byte fragmentBuffer[MAX_MESSAGE_SIZE];
  137. // reliable messages
  138. idMsgQueue reliableSend;
  139. idMsgQueue reliableReceive;
  140. private:
  141. void WriteMessageData( idBitMsg &out, const idBitMsg &msg );
  142. bool ReadMessageData( idBitMsg &out, const idBitMsg &msg );
  143. void UpdateOutgoingRate( const int time, const int size );
  144. void UpdateIncomingRate( const int time, const int size );
  145. void UpdatePacketLoss( const int time, const int numReceived, const int numDropped );
  146. };
  147. #endif /* !__MSGCHANNEL_H__ */