Panda3D
socketStream.I
1 // Filename: socketStream.I
2 // Created by: drose (15Oct02)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 
16 ////////////////////////////////////////////////////////////////////
17 // Function: SSReader::receive_datagram
18 // Access: Published
19 // Description: Receives a datagram over the socket by expecting a
20 // little-endian 16-bit byte count as a prefix. If the
21 // socket stream is non-blocking, may return false if
22 // the data is not available; otherwise, returns false
23 // only if the socket closes.
24 ////////////////////////////////////////////////////////////////////
25 INLINE bool SSReader::
26 receive_datagram(Datagram &dg) {
27 #ifdef SIMULATE_NETWORK_DELAY
28  if (_delay_active) {
29  while (do_receive_datagram(dg)) {
30  delay_datagram(dg);
31  }
32  return get_delayed(dg);
33  }
34 
35  // Pick up any datagrams that might have been leftover in the queue
36  // when we disabled the delay.
37  if (get_delayed(dg)) {
38  return true;
39  }
40 #endif // SIMULATE_NETWORK_DELAY
41 
42  return do_receive_datagram(dg);
43 }
44 
45 ////////////////////////////////////////////////////////////////////
46 // Function: SSReader::set_tcp_header_size
47 // Access: Published
48 // Description: Sets the header size for datagrams. At the present,
49 // legal values for this are 0, 2, or 4; this specifies
50 // the number of bytes to use encode the datagram length
51 // at the start of each TCP datagram. Sender and
52 // receiver must independently agree on this.
53 ////////////////////////////////////////////////////////////////////
54 INLINE void SSReader::
55 set_tcp_header_size(int tcp_header_size) {
56  nassertv(tcp_header_size == 0 || tcp_header_size == 2 || tcp_header_size == 4);
57  _tcp_header_size = tcp_header_size;
58 }
59 
60 ////////////////////////////////////////////////////////////////////
61 // Function: SSReader::get_tcp_header_size
62 // Access: Published
63 // Description: Returns the header size for datagrams. See
64 // set_tcp_header_size().
65 ////////////////////////////////////////////////////////////////////
66 INLINE int SSReader::
67 get_tcp_header_size() const {
68  return _tcp_header_size;
69 }
70 
71 ////////////////////////////////////////////////////////////////////
72 // Function: SSWriter::set_collect_tcp
73 // Access: Published
74 // Description: Enables or disables "collect-tcp" mode. In this
75 // mode, individual TCP packets are not sent
76 // immediately, but rather they are collected together
77 // and accumulated to be sent periodically as one larger
78 // TCP packet. This cuts down on overhead from the
79 // TCP/IP protocol, especially if many small packets
80 // need to be sent on the same connection, but it
81 // introduces additional latency (since packets must be
82 // held before they can be sent).
83 //
84 // See set_collect_tcp_interval() to specify the
85 // interval of time for which to hold packets before
86 // sending them.
87 //
88 // If you enable this mode, you may also need to
89 // periodically call consider_flush() to flush the queue
90 // if no packets have been sent recently.
91 ////////////////////////////////////////////////////////////////////
92 INLINE void SSWriter::
93 set_collect_tcp(bool collect_tcp) {
94  _collect_tcp = collect_tcp;
95 }
96 
97 ////////////////////////////////////////////////////////////////////
98 // Function: SSWriter::get_collect_tcp
99 // Access: Published
100 // Description: Returns the current setting of "collect-tcp" mode.
101 // See set_collect_tcp().
102 ////////////////////////////////////////////////////////////////////
103 INLINE bool SSWriter::
104 get_collect_tcp() const {
105  return _collect_tcp;
106 }
107 
108 ////////////////////////////////////////////////////////////////////
109 // Function: SSWriter::set_collect_tcp_interval
110 // Access: Published
111 // Description: Specifies the interval in time, in seconds, for which
112 // to hold TCP packets before sending all of the
113 // recently received packets at once. This only has
114 // meaning if "collect-tcp" mode is enabled; see
115 // set_collect_tcp().
116 ////////////////////////////////////////////////////////////////////
117 INLINE void SSWriter::
118 set_collect_tcp_interval(double interval) {
119  _collect_tcp_interval = interval;
120 }
121 
122 ////////////////////////////////////////////////////////////////////
123 // Function: SSWriter::get_collect_tcp_interval
124 // Access: Published
125 // Description: Returns the interval in time, in seconds, for which
126 // to hold TCP packets before sending all of the
127 // recently received packets at once. This only has
128 // meaning if "collect-tcp" mode is enabled; see
129 // set_collect_tcp().
130 ////////////////////////////////////////////////////////////////////
131 INLINE double SSWriter::
132 get_collect_tcp_interval() const {
133  return _collect_tcp_interval;
134 }
135 
136 ////////////////////////////////////////////////////////////////////
137 // Function: SSWriter::set_tcp_header_size
138 // Access: Published
139 // Description: Sets the header size for datagrams. At the present,
140 // legal values for this are 0, 2, or 4; this specifies
141 // the number of bytes to use encode the datagram length
142 // at the start of each TCP datagram. Sender and
143 // receiver must independently agree on this.
144 ////////////////////////////////////////////////////////////////////
145 INLINE void SSWriter::
146 set_tcp_header_size(int tcp_header_size) {
147  nassertv(tcp_header_size == 0 || tcp_header_size == 2 || tcp_header_size == 4);
148  _tcp_header_size = tcp_header_size;
149 }
150 
151 ////////////////////////////////////////////////////////////////////
152 // Function: SSWriter::get_tcp_header_size
153 // Access: Published
154 // Description: Returns the header size for datagrams. See
155 // set_tcp_header_size().
156 ////////////////////////////////////////////////////////////////////
157 INLINE int SSWriter::
158 get_tcp_header_size() const {
159  return _tcp_header_size;
160 }
161 
162 ////////////////////////////////////////////////////////////////////
163 // Function: SSWriter::consider_flush
164 // Access: Published
165 // Description: Sends the most recently queued data if enough time
166 // has elapsed. This only has meaning if
167 // set_collect_tcp() has been set to true.
168 ////////////////////////////////////////////////////////////////////
169 INLINE bool SSWriter::
170 consider_flush() {
171  if (!_collect_tcp) {
172  return flush();
173 
174  } else {
175  double elapsed =
176  TrueClock::get_global_ptr()->get_short_time() - _queued_data_start;
177  // If the elapsed time is negative, someone must have reset the
178  // clock back, so just go ahead and flush.
179  if (elapsed < 0.0 || elapsed >= _collect_tcp_interval) {
180  return flush();
181  }
182  }
183 
184  return true;
185 }
186 
187 ////////////////////////////////////////////////////////////////////
188 // Function: SSWriter::flush
189 // Access: Published
190 // Description: Sends the most recently queued data now. This only
191 // has meaning if set_collect_tcp() has been set to
192 // true.
193 ////////////////////////////////////////////////////////////////////
194 INLINE bool SSWriter::
195 flush() {
196  _ostream->flush();
197  _queued_data_start = TrueClock::get_global_ptr()->get_short_time();
198  return !is_closed();
199 }
200 
201 ////////////////////////////////////////////////////////////////////
202 // Function: ISocketStream::Constructor
203 // Access: Public
204 // Description:
205 ////////////////////////////////////////////////////////////////////
206 INLINE ISocketStream::
207 ISocketStream(streambuf *buf) : istream(buf), SSReader(this) {
208  _channel = NULL;
209 }
210 
211 ////////////////////////////////////////////////////////////////////
212 // Function: OSocketStream::Constructor
213 // Access: Public
214 // Description:
215 ////////////////////////////////////////////////////////////////////
216 INLINE OSocketStream::
217 OSocketStream(streambuf *buf) : ostream(buf), SSWriter(this) {
218 }
219 
220 ////////////////////////////////////////////////////////////////////
221 // Function: OSocketStream::flush
222 // Access: Published
223 // Description: Sends the most recently queued data now. This only
224 // has meaning if set_collect_tcp() has been set to
225 // true.
226 ////////////////////////////////////////////////////////////////////
227 INLINE bool OSocketStream::
228 flush() {
229  return SSWriter::flush();
230 }
231 
232 ////////////////////////////////////////////////////////////////////
233 // Function: SocketStream::Constructor
234 // Access: Public
235 // Description:
236 ////////////////////////////////////////////////////////////////////
237 INLINE SocketStream::
238 SocketStream(streambuf *buf) : iostream(buf), SSReader(this), SSWriter(this) {
239 }
240 
241 ////////////////////////////////////////////////////////////////////
242 // Function: SocketStream::set_tcp_header_size
243 // Access: Published
244 // Description: Sets the header size for datagrams. At the present,
245 // legal values for this are 0, 2, or 4; this specifies
246 // the number of bytes to use encode the datagram length
247 // at the start of each TCP datagram. Sender and
248 // receiver must independently agree on this.
249 ////////////////////////////////////////////////////////////////////
250 INLINE void SocketStream::
251 set_tcp_header_size(int tcp_header_size) {
252  SSReader::set_tcp_header_size(tcp_header_size);
253  SSWriter::set_tcp_header_size(tcp_header_size);
254 }
255 
256 ////////////////////////////////////////////////////////////////////
257 // Function: SocketStream::get_tcp_header_size
258 // Access: Published
259 // Description: Returns the header size for datagrams. See
260 // set_tcp_header_size().
261 ////////////////////////////////////////////////////////////////////
262 INLINE int SocketStream::
263 get_tcp_header_size() const {
264  return SSReader::get_tcp_header_size();
265 }
266 
267 ////////////////////////////////////////////////////////////////////
268 // Function: SocketStream::flush
269 // Access: Published
270 // Description: Sends the most recently queued data now. This only
271 // has meaning if set_collect_tcp() has been set to
272 // true.
273 ////////////////////////////////////////////////////////////////////
274 INLINE bool SocketStream::
275 flush() {
276  return SSWriter::flush();
277 }
static TrueClock * get_global_ptr()
Returns a pointer to the one TrueClock object in the world.
Definition: trueClock.I:81
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
Definition: datagram.h:43