Panda3D
|
00001 // Filename: socketStream.I 00002 // Created by: drose (15Oct02) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) Carnegie Mellon University. All rights reserved. 00008 // 00009 // All use of this software is subject to the terms of the revised BSD 00010 // license. You should have received a copy of this license along 00011 // with this source code in a file named "LICENSE." 00012 // 00013 //////////////////////////////////////////////////////////////////// 00014 00015 00016 //////////////////////////////////////////////////////////////////// 00017 // Function: SSReader::receive_datagram 00018 // Access: Published 00019 // Description: Receives a datagram over the socket by expecting a 00020 // little-endian 16-bit byte count as a prefix. If the 00021 // socket stream is non-blocking, may return false if 00022 // the data is not available; otherwise, returns false 00023 // only if the socket closes. 00024 //////////////////////////////////////////////////////////////////// 00025 INLINE bool SSReader:: 00026 receive_datagram(Datagram &dg) { 00027 #ifdef SIMULATE_NETWORK_DELAY 00028 if (_delay_active) { 00029 while (do_receive_datagram(dg)) { 00030 delay_datagram(dg); 00031 } 00032 return get_delayed(dg); 00033 } 00034 00035 // Pick up any datagrams that might have been leftover in the queue 00036 // when we disabled the delay. 00037 if (get_delayed(dg)) { 00038 return true; 00039 } 00040 #endif // SIMULATE_NETWORK_DELAY 00041 00042 return do_receive_datagram(dg); 00043 } 00044 00045 //////////////////////////////////////////////////////////////////// 00046 // Function: SSReader::set_tcp_header_size 00047 // Access: Published 00048 // Description: Sets the header size for datagrams. At the present, 00049 // legal values for this are 0, 2, or 4; this specifies 00050 // the number of bytes to use encode the datagram length 00051 // at the start of each TCP datagram. Sender and 00052 // receiver must independently agree on this. 00053 //////////////////////////////////////////////////////////////////// 00054 INLINE void SSReader:: 00055 set_tcp_header_size(int tcp_header_size) { 00056 nassertv(tcp_header_size == 0 || tcp_header_size == 2 || tcp_header_size == 4); 00057 _tcp_header_size = tcp_header_size; 00058 } 00059 00060 //////////////////////////////////////////////////////////////////// 00061 // Function: SSReader::get_tcp_header_size 00062 // Access: Published 00063 // Description: Returns the header size for datagrams. See 00064 // set_tcp_header_size(). 00065 //////////////////////////////////////////////////////////////////// 00066 INLINE int SSReader:: 00067 get_tcp_header_size() const { 00068 return _tcp_header_size; 00069 } 00070 00071 //////////////////////////////////////////////////////////////////// 00072 // Function: SSWriter::set_collect_tcp 00073 // Access: Published 00074 // Description: Enables or disables "collect-tcp" mode. In this 00075 // mode, individual TCP packets are not sent 00076 // immediately, but rather they are collected together 00077 // and accumulated to be sent periodically as one larger 00078 // TCP packet. This cuts down on overhead from the 00079 // TCP/IP protocol, especially if many small packets 00080 // need to be sent on the same connection, but it 00081 // introduces additional latency (since packets must be 00082 // held before they can be sent). 00083 // 00084 // See set_collect_tcp_interval() to specify the 00085 // interval of time for which to hold packets before 00086 // sending them. 00087 // 00088 // If you enable this mode, you may also need to 00089 // periodically call consider_flush() to flush the queue 00090 // if no packets have been sent recently. 00091 //////////////////////////////////////////////////////////////////// 00092 INLINE void SSWriter:: 00093 set_collect_tcp(bool collect_tcp) { 00094 _collect_tcp = collect_tcp; 00095 } 00096 00097 //////////////////////////////////////////////////////////////////// 00098 // Function: SSWriter::get_collect_tcp 00099 // Access: Published 00100 // Description: Returns the current setting of "collect-tcp" mode. 00101 // See set_collect_tcp(). 00102 //////////////////////////////////////////////////////////////////// 00103 INLINE bool SSWriter:: 00104 get_collect_tcp() const { 00105 return _collect_tcp; 00106 } 00107 00108 //////////////////////////////////////////////////////////////////// 00109 // Function: SSWriter::set_collect_tcp_interval 00110 // Access: Published 00111 // Description: Specifies the interval in time, in seconds, for which 00112 // to hold TCP packets before sending all of the 00113 // recently received packets at once. This only has 00114 // meaning if "collect-tcp" mode is enabled; see 00115 // set_collect_tcp(). 00116 //////////////////////////////////////////////////////////////////// 00117 INLINE void SSWriter:: 00118 set_collect_tcp_interval(double interval) { 00119 _collect_tcp_interval = interval; 00120 } 00121 00122 //////////////////////////////////////////////////////////////////// 00123 // Function: SSWriter::get_collect_tcp_interval 00124 // Access: Published 00125 // Description: Returns the interval in time, in seconds, for which 00126 // to hold TCP packets before sending all of the 00127 // recently received packets at once. This only has 00128 // meaning if "collect-tcp" mode is enabled; see 00129 // set_collect_tcp(). 00130 //////////////////////////////////////////////////////////////////// 00131 INLINE double SSWriter:: 00132 get_collect_tcp_interval() const { 00133 return _collect_tcp_interval; 00134 } 00135 00136 //////////////////////////////////////////////////////////////////// 00137 // Function: SSWriter::set_tcp_header_size 00138 // Access: Published 00139 // Description: Sets the header size for datagrams. At the present, 00140 // legal values for this are 0, 2, or 4; this specifies 00141 // the number of bytes to use encode the datagram length 00142 // at the start of each TCP datagram. Sender and 00143 // receiver must independently agree on this. 00144 //////////////////////////////////////////////////////////////////// 00145 INLINE void SSWriter:: 00146 set_tcp_header_size(int tcp_header_size) { 00147 nassertv(tcp_header_size == 0 || tcp_header_size == 2 || tcp_header_size == 4); 00148 _tcp_header_size = tcp_header_size; 00149 } 00150 00151 //////////////////////////////////////////////////////////////////// 00152 // Function: SSWriter::get_tcp_header_size 00153 // Access: Published 00154 // Description: Returns the header size for datagrams. See 00155 // set_tcp_header_size(). 00156 //////////////////////////////////////////////////////////////////// 00157 INLINE int SSWriter:: 00158 get_tcp_header_size() const { 00159 return _tcp_header_size; 00160 } 00161 00162 //////////////////////////////////////////////////////////////////// 00163 // Function: SSWriter::consider_flush 00164 // Access: Published 00165 // Description: Sends the most recently queued data if enough time 00166 // has elapsed. This only has meaning if 00167 // set_collect_tcp() has been set to true. 00168 //////////////////////////////////////////////////////////////////// 00169 INLINE bool SSWriter:: 00170 consider_flush() { 00171 if (!_collect_tcp) { 00172 return flush(); 00173 00174 } else { 00175 double elapsed = 00176 TrueClock::get_global_ptr()->get_short_time() - _queued_data_start; 00177 // If the elapsed time is negative, someone must have reset the 00178 // clock back, so just go ahead and flush. 00179 if (elapsed < 0.0 || elapsed >= _collect_tcp_interval) { 00180 return flush(); 00181 } 00182 } 00183 00184 return true; 00185 } 00186 00187 //////////////////////////////////////////////////////////////////// 00188 // Function: SSWriter::flush 00189 // Access: Published 00190 // Description: Sends the most recently queued data now. This only 00191 // has meaning if set_collect_tcp() has been set to 00192 // true. 00193 //////////////////////////////////////////////////////////////////// 00194 INLINE bool SSWriter:: 00195 flush() { 00196 _ostream->flush(); 00197 _queued_data_start = TrueClock::get_global_ptr()->get_short_time(); 00198 return !is_closed(); 00199 } 00200 00201 //////////////////////////////////////////////////////////////////// 00202 // Function: ISocketStream::Constructor 00203 // Access: Public 00204 // Description: 00205 //////////////////////////////////////////////////////////////////// 00206 INLINE ISocketStream:: 00207 ISocketStream(streambuf *buf) : istream(buf), SSReader(this) { 00208 _channel = NULL; 00209 } 00210 00211 //////////////////////////////////////////////////////////////////// 00212 // Function: OSocketStream::Constructor 00213 // Access: Public 00214 // Description: 00215 //////////////////////////////////////////////////////////////////// 00216 INLINE OSocketStream:: 00217 OSocketStream(streambuf *buf) : ostream(buf), SSWriter(this) { 00218 } 00219 00220 //////////////////////////////////////////////////////////////////// 00221 // Function: OSocketStream::flush 00222 // Access: Published 00223 // Description: Sends the most recently queued data now. This only 00224 // has meaning if set_collect_tcp() has been set to 00225 // true. 00226 //////////////////////////////////////////////////////////////////// 00227 INLINE bool OSocketStream:: 00228 flush() { 00229 return SSWriter::flush(); 00230 } 00231 00232 //////////////////////////////////////////////////////////////////// 00233 // Function: SocketStream::Constructor 00234 // Access: Public 00235 // Description: 00236 //////////////////////////////////////////////////////////////////// 00237 INLINE SocketStream:: 00238 SocketStream(streambuf *buf) : iostream(buf), SSReader(this), SSWriter(this) { 00239 } 00240 00241 //////////////////////////////////////////////////////////////////// 00242 // Function: SocketStream::set_tcp_header_size 00243 // Access: Published 00244 // Description: Sets the header size for datagrams. At the present, 00245 // legal values for this are 0, 2, or 4; this specifies 00246 // the number of bytes to use encode the datagram length 00247 // at the start of each TCP datagram. Sender and 00248 // receiver must independently agree on this. 00249 //////////////////////////////////////////////////////////////////// 00250 INLINE void SocketStream:: 00251 set_tcp_header_size(int tcp_header_size) { 00252 SSReader::set_tcp_header_size(tcp_header_size); 00253 SSWriter::set_tcp_header_size(tcp_header_size); 00254 } 00255 00256 //////////////////////////////////////////////////////////////////// 00257 // Function: SocketStream::get_tcp_header_size 00258 // Access: Published 00259 // Description: Returns the header size for datagrams. See 00260 // set_tcp_header_size(). 00261 //////////////////////////////////////////////////////////////////// 00262 INLINE int SocketStream:: 00263 get_tcp_header_size() const { 00264 return SSReader::get_tcp_header_size(); 00265 } 00266 00267 //////////////////////////////////////////////////////////////////// 00268 // Function: SocketStream::flush 00269 // Access: Published 00270 // Description: Sends the most recently queued data now. This only 00271 // has meaning if set_collect_tcp() has been set to 00272 // true. 00273 //////////////////////////////////////////////////////////////////// 00274 INLINE bool SocketStream:: 00275 flush() { 00276 return SSWriter::flush(); 00277 }