219 lines
6 KiB
Text
219 lines
6 KiB
Text
|
/**
|
||
|
* PANDA 3D SOFTWARE
|
||
|
* Copyright (c) Carnegie Mellon University. All rights reserved.
|
||
|
*
|
||
|
* All use of this software is subject to the terms of the revised BSD
|
||
|
* license. You should have received a copy of this license along
|
||
|
* with this source code in a file named "LICENSE."
|
||
|
*
|
||
|
* @file socketStream.I
|
||
|
* @author drose
|
||
|
* @date 2002-10-15
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* Receives a datagram over the socket by expecting a little-endian 16-bit
|
||
|
* byte count as a prefix. If the socket stream is non-blocking, may return
|
||
|
* false if the data is not available; otherwise, returns false only if the
|
||
|
* socket closes.
|
||
|
*/
|
||
|
INLINE bool SSReader::
|
||
|
receive_datagram(Datagram &dg) {
|
||
|
#ifdef SIMULATE_NETWORK_DELAY
|
||
|
if (_delay_active) {
|
||
|
while (do_receive_datagram(dg)) {
|
||
|
delay_datagram(dg);
|
||
|
}
|
||
|
return get_delayed(dg);
|
||
|
}
|
||
|
|
||
|
// Pick up any datagrams that might have been leftover in the queue when we
|
||
|
// disabled the delay.
|
||
|
if (get_delayed(dg)) {
|
||
|
return true;
|
||
|
}
|
||
|
#endif // SIMULATE_NETWORK_DELAY
|
||
|
|
||
|
return do_receive_datagram(dg);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Sets the header size for datagrams. At the present, legal values for this
|
||
|
* are 0, 2, or 4; this specifies the number of bytes to use encode the
|
||
|
* datagram length at the start of each TCP datagram. Sender and receiver
|
||
|
* must independently agree on this.
|
||
|
*/
|
||
|
INLINE void SSReader::
|
||
|
set_tcp_header_size(int tcp_header_size) {
|
||
|
nassertv(tcp_header_size == 0 || tcp_header_size == 2 || tcp_header_size == 4);
|
||
|
_tcp_header_size = tcp_header_size;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns the header size for datagrams. See set_tcp_header_size().
|
||
|
*/
|
||
|
INLINE int SSReader::
|
||
|
get_tcp_header_size() const {
|
||
|
return _tcp_header_size;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Enables or disables "collect-tcp" mode. In this mode, individual TCP
|
||
|
* packets are not sent immediately, but rather they are collected together
|
||
|
* and accumulated to be sent periodically as one larger TCP packet. This
|
||
|
* cuts down on overhead from the TCP/IP protocol, especially if many small
|
||
|
* packets need to be sent on the same connection, but it introduces
|
||
|
* additional latency (since packets must be held before they can be sent).
|
||
|
*
|
||
|
* See set_collect_tcp_interval() to specify the interval of time for which to
|
||
|
* hold packets before sending them.
|
||
|
*
|
||
|
* If you enable this mode, you may also need to periodically call
|
||
|
* consider_flush() to flush the queue if no packets have been sent recently.
|
||
|
*/
|
||
|
INLINE void SSWriter::
|
||
|
set_collect_tcp(bool collect_tcp) {
|
||
|
_collect_tcp = collect_tcp;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns the current setting of "collect-tcp" mode. See set_collect_tcp().
|
||
|
*/
|
||
|
INLINE bool SSWriter::
|
||
|
get_collect_tcp() const {
|
||
|
return _collect_tcp;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Specifies the interval in time, in seconds, for which to hold TCP packets
|
||
|
* before sending all of the recently received packets at once. This only has
|
||
|
* meaning if "collect-tcp" mode is enabled; see set_collect_tcp().
|
||
|
*/
|
||
|
INLINE void SSWriter::
|
||
|
set_collect_tcp_interval(double interval) {
|
||
|
_collect_tcp_interval = interval;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns the interval in time, in seconds, for which to hold TCP packets
|
||
|
* before sending all of the recently received packets at once. This only has
|
||
|
* meaning if "collect-tcp" mode is enabled; see set_collect_tcp().
|
||
|
*/
|
||
|
INLINE double SSWriter::
|
||
|
get_collect_tcp_interval() const {
|
||
|
return _collect_tcp_interval;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Sets the header size for datagrams. At the present, legal values for this
|
||
|
* are 0, 2, or 4; this specifies the number of bytes to use encode the
|
||
|
* datagram length at the start of each TCP datagram. Sender and receiver
|
||
|
* must independently agree on this.
|
||
|
*/
|
||
|
INLINE void SSWriter::
|
||
|
set_tcp_header_size(int tcp_header_size) {
|
||
|
nassertv(tcp_header_size == 0 || tcp_header_size == 2 || tcp_header_size == 4);
|
||
|
_tcp_header_size = tcp_header_size;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns the header size for datagrams. See set_tcp_header_size().
|
||
|
*/
|
||
|
INLINE int SSWriter::
|
||
|
get_tcp_header_size() const {
|
||
|
return _tcp_header_size;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Sends the most recently queued data if enough time has elapsed. This only
|
||
|
* has meaning if set_collect_tcp() has been set to true.
|
||
|
*/
|
||
|
INLINE bool SSWriter::
|
||
|
consider_flush() {
|
||
|
if (!_collect_tcp) {
|
||
|
return flush();
|
||
|
|
||
|
} else {
|
||
|
double elapsed =
|
||
|
TrueClock::get_global_ptr()->get_short_time() - _queued_data_start;
|
||
|
// If the elapsed time is negative, someone must have reset the clock
|
||
|
// back, so just go ahead and flush.
|
||
|
if (elapsed < 0.0 || elapsed >= _collect_tcp_interval) {
|
||
|
return flush();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Sends the most recently queued data now. This only has meaning if
|
||
|
* set_collect_tcp() has been set to true.
|
||
|
*/
|
||
|
INLINE bool SSWriter::
|
||
|
flush() {
|
||
|
_ostream->flush();
|
||
|
_queued_data_start = TrueClock::get_global_ptr()->get_short_time();
|
||
|
return !is_closed();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
*
|
||
|
*/
|
||
|
INLINE ISocketStream::
|
||
|
ISocketStream(std::streambuf *buf) : std::istream(buf), SSReader(this) {
|
||
|
_channel = nullptr;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
*
|
||
|
*/
|
||
|
INLINE OSocketStream::
|
||
|
OSocketStream(std::streambuf *buf) : std::ostream(buf), SSWriter(this) {
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Sends the most recently queued data now. This only has meaning if
|
||
|
* set_collect_tcp() has been set to true.
|
||
|
*/
|
||
|
INLINE bool OSocketStream::
|
||
|
flush() {
|
||
|
return SSWriter::flush();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
*
|
||
|
*/
|
||
|
INLINE SocketStream::
|
||
|
SocketStream(std::streambuf *buf) : std::iostream(buf), SSReader(this), SSWriter(this) {
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Sets the header size for datagrams. At the present, legal values for this
|
||
|
* are 0, 2, or 4; this specifies the number of bytes to use encode the
|
||
|
* datagram length at the start of each TCP datagram. Sender and receiver
|
||
|
* must independently agree on this.
|
||
|
*/
|
||
|
INLINE void SocketStream::
|
||
|
set_tcp_header_size(int tcp_header_size) {
|
||
|
SSReader::set_tcp_header_size(tcp_header_size);
|
||
|
SSWriter::set_tcp_header_size(tcp_header_size);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns the header size for datagrams. See set_tcp_header_size().
|
||
|
*/
|
||
|
INLINE int SocketStream::
|
||
|
get_tcp_header_size() const {
|
||
|
return SSReader::get_tcp_header_size();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Sends the most recently queued data now. This only has meaning if
|
||
|
* set_collect_tcp() has been set to true.
|
||
|
*/
|
||
|
INLINE bool SocketStream::
|
||
|
flush() {
|
||
|
return SSWriter::flush();
|
||
|
}
|