15 #include "connection.h" 16 #include "connectionManager.h" 17 #include "netDatagram.h" 18 #include "datagramTCPHeader.h" 19 #include "datagramUDPHeader.h" 20 #include "config_net.h" 21 #include "config_express.h" 22 #include "trueClock.h" 24 #include "lightReMutexHolder.h" 25 #include "socket_ip.h" 26 #include "socket_tcp.h" 27 #include "socket_udp.h" 44 _collect_tcp = collect_tcp;
45 _collect_tcp_interval = collect_tcp_interval;
46 _queued_data_start = 0.0;
49 #if defined(HAVE_THREADS) && defined(SIMPLE_THREADS) 54 <<
"Unable to set non-blocking status on socket\n";
67 <<
"Deleting connection " << (
void *)
this <<
"\n";
134 _collect_tcp = collect_tcp;
159 _collect_tcp_interval = interval;
173 return _collect_tcp_interval;
195 if (elapsed < 0.0 || elapsed >= _collect_tcp_interval) {
223 // Function: Connection::set_nonblock
225 // Description: Sets whether nonblocking I/O should be in effect.
228 set_nonblock(bool flag) {
230 _socket->SetNonBlocking();
232 _socket->SetBlocking();
252 DCAST_INTO_V(tcp, _socket);
300 DCAST_INTO_V(tcp, _socket);
334 DCAST_INTO_V(tcp, _socket);
359 send_datagram(
const NetDatagram &datagram,
int tcp_header_size) {
360 nassertr(_socket != (
Socket_IP *)NULL,
false);
365 DCAST_INTO_R(udp, _socket,
false);
373 if (net_cat.is_debug()) {
377 int bytes_to_send = data.length();
380 bool okflag = udp->
SendTo(data, addr);
381 #if defined(HAVE_THREADS) && defined(SIMPLE_THREADS) 384 okflag = udp->
SendTo(data, addr);
386 #endif // SIMPLE_THREADS 388 if (net_cat.is_spam()) {
390 <<
"Sent UDP datagram with " 391 << bytes_to_send <<
" bytes to " << (
void *)
this 392 <<
", ok = " << okflag <<
"\n";
395 return check_send_error(okflag);
399 if (tcp_header_size == 2 && datagram.
get_length() >= 0x10000) {
401 <<
"Attempt to send TCP datagram of " << datagram.
get_length()
402 <<
" bytes--too long!\n";
403 nassert_raise(
"Datagram too long");
414 if (net_cat.is_debug()) {
435 nassertr(_socket != (
Socket_IP *)NULL,
false);
440 DCAST_INTO_R(udp, _socket,
false);
446 bool okflag = udp->
SendTo(data, addr);
447 #if defined(HAVE_THREADS) && defined(SIMPLE_THREADS) 450 okflag = udp->
SendTo(data, addr);
452 #endif // SIMPLE_THREADS 454 if (net_cat.is_spam()) {
456 <<
"Sent UDP datagram with " 457 << data.size() <<
" bytes to " << (
void *)
this 458 <<
", ok = " << okflag <<
"\n";
461 return check_send_error(okflag);
485 if (_queued_data.empty()) {
491 if (net_cat.is_spam()) {
493 <<
"Sending " << _queued_count <<
" TCP datagram(s) with " 494 << _queued_data.length() <<
" total bytes to " << (
void *)
this <<
"\n";
498 DCAST_INTO_R(tcp, _socket,
false);
501 _queued_data.swap(sending_data);
506 #if defined(HAVE_THREADS) && defined(SIMPLE_THREADS) 507 int max_send = net_max_write_per_epoch;
508 int data_sent = tcp->SendData(sending_data.data(), min((
size_t)max_send, sending_data.size()));
509 bool okflag = (data_sent == (int)sending_data.size());
513 total_sent += data_sent;
515 double last_report = 0;
516 while (!okflag && tcp->
Active() &&
517 (data_sent > 0 || tcp->
GetLastError() == LOCAL_BLOCKING_ERROR)) {
518 if (data_sent == 0) {
523 data_sent = tcp->SendData(sending_data.data() + total_sent, min((
size_t)max_send, sending_data.size() - total_sent));
525 total_sent += data_sent;
527 okflag = (total_sent == (int)sending_data.size());
531 #else // SIMPLE_THREADS 532 int data_sent = tcp->SendData(sending_data);
533 bool okflag = (data_sent == (int)sending_data.size());
535 #endif // SIMPLE_THREADS 537 return check_send_error(okflag);
547 check_send_error(
bool okflag) {
550 if (abort_send_error) {
551 nassertr(
false,
false);
557 _manager->flush_read_connection(
this);
558 _manager->connection_reset(
this, okflag);
int SetRecvBufferSize(int size)
Ok it sets the recv buffer size for both tcp and UDP.
static TrueClock * get_global_ptr()
Returns a pointer to the one TrueClock object in the world.
Base functionality for a TCP connected socket This class is pretty useless by itself but it does hide...
bool is_exact_type(TypeHandle handle) const
Returns true if the current object is the indicated type exactly.
void set_keep_alive(bool flag)
Sets whether the connection is periodically tested to see if it is still alive.
A specific kind of Datagram, especially for sending across or receiving from a network.
Base functionality for a INET domain Socket this call should be the starting point for all other unix...
int SetNonBlocking()
this function will throw a socket into non-blocking mode
This is a convenience class to specialize ConfigVariable as a boolean type.
void set_ip_type_of_service(int tos)
Sets IP type-of-service and precedence.
The primary interface to the low-level networking layer in this package.
~Connection()
Closes a connection.
int DontLinger()
Turn off the linger flag.
void set_linger(bool flag, double time)
Sets the time to linger on close if data is present.
static void consider_yield()
Possibly suspends the current thread for the rest of the current epoch, if it has run for enough this...
Socket_Address GetPeerName(void) const
Wrapper on berkly getpeername...
bool Active()
Ask if the socket is open (allocated)
void set_max_segment(int size)
Sets the maximum segment size.
static void force_yield()
Suspends the current thread for the rest of the current epoch.
void set_ip_time_to_live(int ttl)
Sets IP time-to-live.
Connection(ConnectionManager *manager, Socket_IP *socket)
Creates a connection.
const NetAddress & get_address() const
Retrieves the host from which the datagram was read, or to which it is scheduled to be sent...
bool get_collect_tcp() const
Returns the current setting of "collect-tcp" mode.
Base functionality for a combination UDP Reader and Writer.
Socket_IP * get_socket() const
Returns the internal Socket_IP that defines the connection.
void set_recv_buffer_size(int size)
Sets the size of the receive buffer, in bytes.
void set_collect_tcp(bool collect_tcp)
Enables or disables "collect-tcp" mode.
ConnectionManager * get_manager() const
Returns a pointer to the ConnectionManager object that serves this connection.
double get_collect_tcp_interval() const
Returns the interval in time, in seconds, for which to hold TCP packets before sending all of the rec...
void set_reuse_addr(bool flag)
Sets whether local address reuse is allowed.
void set_no_delay(bool flag)
If flag is true, this disables the Nagle algorithm, and prevents delaying of send to coalesce packets...
bool consider_flush()
Sends the most recently queued TCP datagram(s) if enough time has elapsed.
A simple place to store and munipulate tcp and port address for communication layer.
Similar to MutexHolder, but for a light reentrant mutex.
NetAddress get_address() const
Returns the address bound to this connection, if it is a TCP connection.
int SetLinger(int interval_seconds=0)
will control the behavior of SO_LINGER for a TCP socket
static int GetLastError()
gets the last errcode from a socket operation
void set_collect_tcp_interval(double interval)
Specifies the interval in time, in seconds, for which to hold TCP packets before sending all of the r...
bool SetReuseAddress(bool flag=true)
Informs a socket to reuse IP address as needed.
void Close()
closes a socket if it is open (allocated)
void set_send_buffer_size(int size)
Sets the size of the send buffer, in bytes.
const Socket_Address & get_addr() const
Returns the Socket_Address for this address.
bool SendTo(const char *data, int len, const Socket_Address &address)
Send data to specified address.
string get_message() const
Returns the datagram's data as a string.
int SetSendBufferSize(int insize)
Just like it sounds.
bool flush()
Sends the most recently queued TCP datagram(s) now.
int SetNoDelay(bool flag=true)
Disable Nagle algorithm.
size_t get_length() const
Returns the number of bytes in the datagram.
Represents a network address to which UDP packets may be sent or to which a TCP socket may be bound...