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