okay, now this should be safe
This commit is contained in:
parent
466a3f7d48
commit
576818d5db
|
|
@ -0,0 +1,36 @@
|
|||
|
||||
|
||||
#define LOCAL_LIBS express pandabase
|
||||
|
||||
#define OTHER_LIBS interrogatedb:c dconfig:c dtoolconfig:m \
|
||||
dtoolutil:c dtoolbase:c dtool:m
|
||||
|
||||
#define BUILD_DIRECTORY [$WANT_NATIVE_NET]
|
||||
|
||||
#begin lib_target
|
||||
#define TARGET nativenet
|
||||
|
||||
#define COMBINED_SOURCES $[TARGET]_composite1.cxx
|
||||
|
||||
#define SOURCES \
|
||||
buffered_datagramconnection.h ringbuffer.h socket_ip.h socket_tcp_listen.h \
|
||||
time_accumulator.h time_out.h buffered_datagramreader.h socket_address.h \
|
||||
socket_portable.h time_base.h time_span.h buffered_datagramwriter.h \
|
||||
socket_base.h socket_selector.h socket_udp_incoming.h time_clock.h \
|
||||
membuffer.h socket_fdset.h socket_tcp.h socket_udp_outgoing.h time_general.h
|
||||
|
||||
|
||||
#define INCLUDED_SOURCES \
|
||||
|
||||
#define INSTALL_HEADERS \
|
||||
buffered_datagramconnection.h ringbuffer.h socket_ip.h socket_tcp_listen.h \
|
||||
time_accumulator.h time_out.h buffered_datagramreader.h socket_address.h \
|
||||
socket_portable.h time_base.h time_span.h buffered_datagramwriter.h \
|
||||
socket_base.h socket_selector.h socket_udp_incoming.h time_clock.h \
|
||||
membuffer.h socket_fdset.h socket_tcp.h socket_udp_outgoing.h time_general.h
|
||||
|
||||
|
||||
#define IGATESCAN all
|
||||
|
||||
#end lib_target
|
||||
|
||||
|
|
@ -1,325 +1,327 @@
|
|||
#ifndef __NONECLOCKING_CONNECTTION_H_
|
||||
#define __NONECLOCKING_CONNECTTION_H_
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Ok here is the base behavior..
|
||||
// A message IO engin that is Smart enough to Do
|
||||
//
|
||||
// 1. Non Blocking Connect .. and Buffer the writes if needed
|
||||
// 2. Handle 1 to N targets for the connection..
|
||||
//
|
||||
// 3. Handle Framing and Unframing properly ..
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
#include "dtoolbase.h"
|
||||
#include <vector>
|
||||
#include "socket_base.h"
|
||||
//#include "../express/datagram.h"
|
||||
#include "datagram.h"
|
||||
|
||||
#include "buffered_datagramreader.h"
|
||||
#include "buffered_datagramwriter.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// there are 3 states
|
||||
//
|
||||
// 1. Socket not even assigned,,,,
|
||||
// 2. Socket Assigned and trying to get a active connect open
|
||||
// 3. Socket is open and writable.. ( Fully powered up )...
|
||||
//
|
||||
///////////////////////////////////////////////////////////////
|
||||
class Buffered_DatagramConnection : protected Socket_TCP
|
||||
{
|
||||
private:
|
||||
struct AddressQueue : private std::vector<Socket_Address> // this is used to do a round robin for addres to connect to ..
|
||||
{
|
||||
size_t _active_index;
|
||||
bool GetNext(Socket_Address &out)
|
||||
{
|
||||
size_t the_size = size();
|
||||
if(the_size == 0)
|
||||
return false;
|
||||
|
||||
if(_active_index >= the_size || _active_index < 0)
|
||||
_active_index = 0;
|
||||
out = (*this)[_active_index++];
|
||||
return true;
|
||||
}
|
||||
|
||||
void clear() { std::vector<Socket_Address>::clear(); };
|
||||
void push_back(Socket_Address &address)
|
||||
{
|
||||
iterator ii;
|
||||
for(ii = begin(); ii != end(); ii++)
|
||||
if(*ii == address)
|
||||
return;
|
||||
std::vector<Socket_Address>::push_back(address);
|
||||
}
|
||||
|
||||
size_t size() { return std::vector<Socket_Address>::size(); };
|
||||
};
|
||||
protected:
|
||||
// c++ upcals for
|
||||
virtual void PostConnect(void) { };
|
||||
virtual void NewWriteBuffer(void) { };
|
||||
///////////////////////////////////////////
|
||||
inline void ClearAll(void);
|
||||
inline bool DoConnect(void); // all the real state magic is in here ...
|
||||
inline bool SendMessageBufferOnly(Datagram &msg); // do not use this .. this is a way for the the COnnecting UPcall to drop messages in queue first..
|
||||
public:
|
||||
PUBLISHED:
|
||||
inline Buffered_DatagramConnection(bool do_blocking_writes, int rbufsize, int wbufsize, int write_flush_point) ;
|
||||
virtual ~Buffered_DatagramConnection(void) ;
|
||||
// the reason thsi all exists
|
||||
inline bool SendMessage(Datagram &msg);
|
||||
inline bool GetMessage(Datagram **val);
|
||||
inline Datagram * GetMessage();
|
||||
inline bool Flush(void);
|
||||
inline void Reset(void);
|
||||
|
||||
// address queue stuff
|
||||
inline size_t AddressQueueSize() { return _Addresslist.size(); };
|
||||
inline void AddAddress(Socket_Address &inadr);
|
||||
inline void ClearAddresses(void);
|
||||
private:
|
||||
Buffered_DatagramWriter _Writer; // buffered writing
|
||||
Buffered_DatagramReader _Reader; // buffered reader
|
||||
AddressQueue _Addresslist; // the location of the round robin address list
|
||||
Socket_Address _Adddress; // the conection address ( active one from list being used)
|
||||
// the local datagram store..
|
||||
Datagram _Msg; // The temp storage for a upcalled message
|
||||
////////////////////////////////
|
||||
// connection state engine /////
|
||||
Time_Out _LastConnectTry; // A Recycle Timer to Stop Connection/spaming..
|
||||
bool _tryingToOpen; // this is a flag that say we are in state 2
|
||||
// state 1 = Active() == false,,
|
||||
// state 2 = Active() == true and _tryingToOpen == true;
|
||||
// state 3 = Active() == true and _tryingToOpen == flase;
|
||||
|
||||
friend class Buffered_DatagramReader;
|
||||
friend class Buffered_DatagramWriter;
|
||||
|
||||
};
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : Buffered_DatagramConnection::ClearAll
|
||||
// Description : used to do a full reset of buffers
|
||||
//
|
||||
// Return type : inline void
|
||||
// Argument : void
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline void Buffered_DatagramConnection::ClearAll(void)
|
||||
{
|
||||
Close();
|
||||
_tryingToOpen = false;
|
||||
_Writer.ReSet();
|
||||
_Reader.ReSet();
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : Buffered_DatagramConnection::DoConnect
|
||||
// Description : This is the function thah does the conection for us
|
||||
//
|
||||
// Return type : inline bool
|
||||
// Argument : void
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline bool Buffered_DatagramConnection::DoConnect(void)
|
||||
{
|
||||
if(Active() != true)
|
||||
{
|
||||
if(_LastConnectTry.Expired() != true)
|
||||
return false;
|
||||
|
||||
if(!_Addresslist.GetNext(_Adddress)) // lookup the proper value...
|
||||
return false;
|
||||
|
||||
if(ActiveOpenNonBlocking(_Adddress) == true)
|
||||
{
|
||||
_LastConnectTry.ReStart();
|
||||
_tryingToOpen = true; // set the flag indicating we are trying to open up
|
||||
SetNonBlocking(); // maybe should be blocking?
|
||||
SetSendBufferSize(1024*50); // we need to hand tune these for the os we are using
|
||||
SetRecvBufferSize(1024*50);
|
||||
NewWriteBuffer();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if(_tryingToOpen) // okay handle the i am connecting state....
|
||||
{
|
||||
Socket_fdset fdset;
|
||||
fdset.setForSocket(*this);
|
||||
Socket_Selector selector;
|
||||
if(selector.WaitFor_All(fdset,0) >0)
|
||||
{
|
||||
_tryingToOpen = false;
|
||||
if(selector._error.IsSetFor(*this) == true) // means we are in errorconnected. else writable
|
||||
{
|
||||
ClearAll();
|
||||
return false; // error on connect
|
||||
}
|
||||
PostConnect();
|
||||
return true; // just got connected
|
||||
}
|
||||
return true; // still connecting
|
||||
}
|
||||
return true;
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : Buffered_DatagramConnection::~Buffered_DatagramConnection
|
||||
// Description :
|
||||
//
|
||||
// Return type : inline
|
||||
// Argument : void
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline Buffered_DatagramConnection::~Buffered_DatagramConnection(void)
|
||||
{
|
||||
Close();
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : Buffered_DatagramConnection::Buffered_DatagramConnection
|
||||
// Description :
|
||||
//
|
||||
// Return type : inline
|
||||
// Argument : bool do_blocking_writes
|
||||
// Argument : int rbufsize
|
||||
// Argument : int wbufsize
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline Buffered_DatagramConnection::Buffered_DatagramConnection(bool do_blocking_writes, int rbufsize, int wbufsize, int write_flush_point)
|
||||
: _Writer(do_blocking_writes,wbufsize,write_flush_point) , _Reader(rbufsize), _Msg() , _LastConnectTry(Time_Span(0,0,0,1,0))
|
||||
{
|
||||
_LastConnectTry.ForceToExpired();
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : Buffered_DatagramConnection::SendMessage
|
||||
// Description : send the message
|
||||
//
|
||||
// Return type : inline bool
|
||||
// Argument : DataGram &msg
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline bool Buffered_DatagramConnection::SendMessage(Datagram &msg)
|
||||
{
|
||||
if(DoConnect() == true)
|
||||
{
|
||||
// printf(" DO SendMessage %d\n",msg.get_length());
|
||||
int val = 0;
|
||||
if(_tryingToOpen) // indicates we are in the process of opening the connection ....just buffer
|
||||
{
|
||||
val = _Writer.AddData(msg.get_data(),msg.get_length());
|
||||
}
|
||||
else
|
||||
{
|
||||
val = _Writer.AddData(msg.get_data(),msg.get_length(),*this);
|
||||
}
|
||||
if(val >= 0)
|
||||
return true;
|
||||
|
||||
// LOGWARNING("Buffered_DatagramConnection::SendMessage->Error On Write--Out Buffer = %d",_Writer.AmountBuffered());
|
||||
ClearAll();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool Buffered_DatagramConnection::SendMessageBufferOnly(Datagram &msg)
|
||||
{
|
||||
int val = _Writer.AddData(msg.get_data(),msg.get_length());
|
||||
if(val >= 0)
|
||||
return true;
|
||||
|
||||
// LOGWARNING("Buffered_DatagramConnection::SendMessageBufferOnly->Error On Write--Out Buffer = %d",_Writer.AmountBuffered());
|
||||
ClearAll();
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : Buffered_DatagramConnection::Init
|
||||
// Description : must be called to set value to the server
|
||||
//
|
||||
// Return type : inline void
|
||||
// Argument : Socket_Address &inadr
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline void Buffered_DatagramConnection::AddAddress(Socket_Address &inadr)
|
||||
{
|
||||
_Addresslist.push_back(inadr);
|
||||
}
|
||||
|
||||
inline void Buffered_DatagramConnection::ClearAddresses(void)
|
||||
{
|
||||
_Addresslist.clear();
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : Buffered_DatagramConnection::GetMessage
|
||||
// Description : read a message
|
||||
//
|
||||
// false means something bad happened..
|
||||
//
|
||||
//
|
||||
// Return type : inline bool
|
||||
// Argument : DataGram **val
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline bool Buffered_DatagramConnection::GetMessage(Datagram **val)
|
||||
{
|
||||
*val = NULL;
|
||||
if(DoConnect() == true && _tryingToOpen != true)
|
||||
{
|
||||
int ans1 = _Reader.PumpMessageReader(_Msg,*this);
|
||||
if(ans1 <0)
|
||||
{
|
||||
// LOGWARNING("Buffered_DatagramConnection::GetMessage->Error On PumpMessageReader--Out Buffer = %d",_Writer.AmountBuffered());
|
||||
ClearAll();
|
||||
return false;
|
||||
}
|
||||
else if (ans1 == 1)
|
||||
{
|
||||
*val = &_Msg;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
inline Datagram * Buffered_DatagramConnection::GetMessage()
|
||||
{
|
||||
Datagram *out = NULL;
|
||||
GetMessage(&out);
|
||||
return out;
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : Buffered_DatagramConnection::Flush
|
||||
// Description : flush all wrightes
|
||||
//
|
||||
// Return type : bool
|
||||
// Argument : void
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool Buffered_DatagramConnection::Flush(void)
|
||||
{
|
||||
if(Active() == true && _tryingToOpen != true )
|
||||
{
|
||||
int flush_resp = _Writer.FlushNoBlock(*this);
|
||||
if(flush_resp < 0)
|
||||
{
|
||||
// LOGWARNING("Buffered_DatagramConnection::Flush->Error On Flush [%d]",GetLastError());
|
||||
// LOGWARNING("Buffered_DatagramConnection::Flush->Error ..Write--Out Buffer = %d",_Writer.AmountBuffered());
|
||||
ClearAll();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : Buffered_DatagramConnection::Flush
|
||||
// Description : Reset
|
||||
//
|
||||
// Return type : void
|
||||
// Argument : void
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline void Buffered_DatagramConnection::Reset()
|
||||
{
|
||||
ClearAll();
|
||||
};
|
||||
|
||||
|
||||
#endif //__NONECLOCKING_CONNECTTION_H_
|
||||
|
||||
#ifndef __NONECLOCKING_CONNECTTION_H_
|
||||
#define __NONECLOCKING_CONNECTTION_H_
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Ok here is the base behavior..
|
||||
// A message IO engin that is Smart enough to Do
|
||||
//
|
||||
// 1. Non Blocking Connect .. and Buffer the writes if needed
|
||||
// 2. Handle 1 to N targets for the connection..
|
||||
//
|
||||
// 3. Handle Framing and Unframing properly ..
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
#include "dtoolbase.h"
|
||||
#include <vector>
|
||||
#include "socket_base.h"
|
||||
//#include "../express/datagram.h"
|
||||
#include "datagram.h"
|
||||
|
||||
#include "buffered_datagramreader.h"
|
||||
#include "buffered_datagramwriter.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// there are 3 states
|
||||
//
|
||||
// 1. Socket not even assigned,,,,
|
||||
// 2. Socket Assigned and trying to get a active connect open
|
||||
// 3. Socket is open and writable.. ( Fully powered up )...
|
||||
//
|
||||
///////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA Buffered_DatagramConnection : protected Socket_TCP
|
||||
{
|
||||
private:
|
||||
struct AddressQueue : private std::vector<Socket_Address> // this is used to do a round robin for addres to connect to ..
|
||||
{
|
||||
size_t _active_index;
|
||||
bool GetNext(Socket_Address &out)
|
||||
{
|
||||
size_t the_size = size();
|
||||
if(the_size == 0)
|
||||
return false;
|
||||
|
||||
if(_active_index >= the_size || _active_index < 0)
|
||||
_active_index = 0;
|
||||
out = (*this)[_active_index++];
|
||||
return true;
|
||||
}
|
||||
|
||||
void clear() { std::vector<Socket_Address>::clear(); };
|
||||
void push_back(Socket_Address &address)
|
||||
{
|
||||
iterator ii;
|
||||
for(ii = begin(); ii != end(); ii++)
|
||||
if(*ii == address)
|
||||
return;
|
||||
std::vector<Socket_Address>::push_back(address);
|
||||
}
|
||||
|
||||
size_t size() { return std::vector<Socket_Address>::size(); };
|
||||
};
|
||||
protected:
|
||||
// c++ upcals for
|
||||
virtual void PostConnect(void) { };
|
||||
virtual void NewWriteBuffer(void) { };
|
||||
///////////////////////////////////////////
|
||||
inline void ClearAll(void);
|
||||
inline bool DoConnect(void); // all the real state magic is in here ...
|
||||
inline bool SendMessageBufferOnly(Datagram &msg); // do not use this .. this is a way for the the COnnecting UPcall to drop messages in queue first..
|
||||
public:
|
||||
inline bool GetMessageInternal(Datagram **val);
|
||||
PUBLISHED:
|
||||
|
||||
inline Buffered_DatagramConnection(bool do_blocking_writes, int rbufsize, int wbufsize, int write_flush_point) ;
|
||||
virtual ~Buffered_DatagramConnection(void) ;
|
||||
// the reason thsi all exists
|
||||
inline bool SendMessage(Datagram &msg);
|
||||
|
||||
inline Datagram * GetMessage();
|
||||
inline bool Flush(void);
|
||||
inline void Reset(void);
|
||||
|
||||
// address queue stuff
|
||||
inline size_t AddressQueueSize() { return _Addresslist.size(); };
|
||||
inline void AddAddress(Socket_Address &inadr);
|
||||
inline void ClearAddresses(void);
|
||||
private:
|
||||
Buffered_DatagramWriter _Writer; // buffered writing
|
||||
Buffered_DatagramReader _Reader; // buffered reader
|
||||
AddressQueue _Addresslist; // the location of the round robin address list
|
||||
Socket_Address _Adddress; // the conection address ( active one from list being used)
|
||||
// the local datagram store..
|
||||
Datagram _Msg; // The temp storage for a upcalled message
|
||||
////////////////////////////////
|
||||
// connection state engine /////
|
||||
Time_Out _LastConnectTry; // A Recycle Timer to Stop Connection/spaming..
|
||||
bool _tryingToOpen; // this is a flag that say we are in state 2
|
||||
// state 1 = Active() == false,,
|
||||
// state 2 = Active() == true and _tryingToOpen == true;
|
||||
// state 3 = Active() == true and _tryingToOpen == flase;
|
||||
|
||||
friend class Buffered_DatagramReader;
|
||||
friend class Buffered_DatagramWriter;
|
||||
|
||||
};
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : Buffered_DatagramConnection::ClearAll
|
||||
// Description : used to do a full reset of buffers
|
||||
//
|
||||
// Return type : inline void
|
||||
// Argument : void
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline void Buffered_DatagramConnection::ClearAll(void)
|
||||
{
|
||||
Close();
|
||||
_tryingToOpen = false;
|
||||
_Writer.ReSet();
|
||||
_Reader.ReSet();
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : Buffered_DatagramConnection::DoConnect
|
||||
// Description : This is the function thah does the conection for us
|
||||
//
|
||||
// Return type : inline bool
|
||||
// Argument : void
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline bool Buffered_DatagramConnection::DoConnect(void)
|
||||
{
|
||||
if(Active() != true)
|
||||
{
|
||||
if(_LastConnectTry.Expired() != true)
|
||||
return false;
|
||||
|
||||
if(!_Addresslist.GetNext(_Adddress)) // lookup the proper value...
|
||||
return false;
|
||||
|
||||
if(ActiveOpenNonBlocking(_Adddress) == true)
|
||||
{
|
||||
_LastConnectTry.ReStart();
|
||||
_tryingToOpen = true; // set the flag indicating we are trying to open up
|
||||
SetNonBlocking(); // maybe should be blocking?
|
||||
SetSendBufferSize(1024*50); // we need to hand tune these for the os we are using
|
||||
SetRecvBufferSize(1024*50);
|
||||
NewWriteBuffer();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if(_tryingToOpen) // okay handle the i am connecting state....
|
||||
{
|
||||
Socket_fdset fdset;
|
||||
fdset.setForSocket(*this);
|
||||
Socket_Selector selector;
|
||||
if(selector.WaitFor_All(fdset,0) >0)
|
||||
{
|
||||
_tryingToOpen = false;
|
||||
if(selector._error.IsSetFor(*this) == true) // means we are in errorconnected. else writable
|
||||
{
|
||||
ClearAll();
|
||||
return false; // error on connect
|
||||
}
|
||||
PostConnect();
|
||||
return true; // just got connected
|
||||
}
|
||||
return true; // still connecting
|
||||
}
|
||||
return true;
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : Buffered_DatagramConnection::~Buffered_DatagramConnection
|
||||
// Description :
|
||||
//
|
||||
// Return type : inline
|
||||
// Argument : void
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline Buffered_DatagramConnection::~Buffered_DatagramConnection(void)
|
||||
{
|
||||
Close();
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : Buffered_DatagramConnection::Buffered_DatagramConnection
|
||||
// Description :
|
||||
//
|
||||
// Return type : inline
|
||||
// Argument : bool do_blocking_writes
|
||||
// Argument : int rbufsize
|
||||
// Argument : int wbufsize
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline Buffered_DatagramConnection::Buffered_DatagramConnection(bool do_blocking_writes, int rbufsize, int wbufsize, int write_flush_point)
|
||||
: _Writer(do_blocking_writes,wbufsize,write_flush_point) , _Reader(rbufsize), _Msg() , _LastConnectTry(Time_Span(0,0,0,1,0))
|
||||
{
|
||||
_LastConnectTry.ForceToExpired();
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : Buffered_DatagramConnection::SendMessage
|
||||
// Description : send the message
|
||||
//
|
||||
// Return type : inline bool
|
||||
// Argument : DataGram &msg
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline bool Buffered_DatagramConnection::SendMessage(Datagram &msg)
|
||||
{
|
||||
if(DoConnect() == true)
|
||||
{
|
||||
// printf(" DO SendMessage %d\n",msg.get_length());
|
||||
int val = 0;
|
||||
if(_tryingToOpen) // indicates we are in the process of opening the connection ....just buffer
|
||||
{
|
||||
val = _Writer.AddData(msg.get_data(),msg.get_length());
|
||||
}
|
||||
else
|
||||
{
|
||||
val = _Writer.AddData(msg.get_data(),msg.get_length(),*this);
|
||||
}
|
||||
if(val >= 0)
|
||||
return true;
|
||||
|
||||
// LOGWARNING("Buffered_DatagramConnection::SendMessage->Error On Write--Out Buffer = %d",_Writer.AmountBuffered());
|
||||
ClearAll();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool Buffered_DatagramConnection::SendMessageBufferOnly(Datagram &msg)
|
||||
{
|
||||
int val = _Writer.AddData(msg.get_data(),msg.get_length());
|
||||
if(val >= 0)
|
||||
return true;
|
||||
|
||||
// LOGWARNING("Buffered_DatagramConnection::SendMessageBufferOnly->Error On Write--Out Buffer = %d",_Writer.AmountBuffered());
|
||||
ClearAll();
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : Buffered_DatagramConnection::Init
|
||||
// Description : must be called to set value to the server
|
||||
//
|
||||
// Return type : inline void
|
||||
// Argument : Socket_Address &inadr
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline void Buffered_DatagramConnection::AddAddress(Socket_Address &inadr)
|
||||
{
|
||||
_Addresslist.push_back(inadr);
|
||||
}
|
||||
|
||||
inline void Buffered_DatagramConnection::ClearAddresses(void)
|
||||
{
|
||||
_Addresslist.clear();
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : Buffered_DatagramConnection::GetMessage
|
||||
// Description : read a message
|
||||
//
|
||||
// false means something bad happened..
|
||||
//
|
||||
//
|
||||
// Return type : inline bool
|
||||
// Argument : DataGram **val
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline bool Buffered_DatagramConnection::GetMessageInternal(Datagram **val)
|
||||
{
|
||||
*val = NULL;
|
||||
if(DoConnect() == true && _tryingToOpen != true)
|
||||
{
|
||||
int ans1 = _Reader.PumpMessageReader(_Msg,*this);
|
||||
if(ans1 <0)
|
||||
{
|
||||
// LOGWARNING("Buffered_DatagramConnection::GetMessage->Error On PumpMessageReader--Out Buffer = %d",_Writer.AmountBuffered());
|
||||
ClearAll();
|
||||
return false;
|
||||
}
|
||||
else if (ans1 == 1)
|
||||
{
|
||||
*val = &_Msg;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
inline Datagram * Buffered_DatagramConnection::GetMessage()
|
||||
{
|
||||
Datagram *out = NULL;
|
||||
GetMessageInternal(&out);
|
||||
return out;
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : Buffered_DatagramConnection::Flush
|
||||
// Description : flush all wrightes
|
||||
//
|
||||
// Return type : bool
|
||||
// Argument : void
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool Buffered_DatagramConnection::Flush(void)
|
||||
{
|
||||
if(Active() == true && _tryingToOpen != true )
|
||||
{
|
||||
int flush_resp = _Writer.FlushNoBlock(*this);
|
||||
if(flush_resp < 0)
|
||||
{
|
||||
// LOGWARNING("Buffered_DatagramConnection::Flush->Error On Flush [%d]",GetLastError());
|
||||
// LOGWARNING("Buffered_DatagramConnection::Flush->Error ..Write--Out Buffer = %d",_Writer.AmountBuffered());
|
||||
ClearAll();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : Buffered_DatagramConnection::Flush
|
||||
// Description : Reset
|
||||
//
|
||||
// Return type : void
|
||||
// Argument : void
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline void Buffered_DatagramConnection::Reset()
|
||||
{
|
||||
ClearAll();
|
||||
};
|
||||
|
||||
|
||||
#endif //__NONECLOCKING_CONNECTTION_H_
|
||||
|
||||
|
|
|
|||
|
|
@ -1,91 +1,91 @@
|
|||
#ifndef __BUFFEREDREADER_GM_H__
|
||||
#define __BUFFEREDREADER_GM_H__
|
||||
|
||||
#include "ringbuffer.h"
|
||||
#include "datagram.h"
|
||||
|
||||
inline unsigned short GetUnsignedShort(char * in)
|
||||
{
|
||||
return *((unsigned short *)in);
|
||||
};
|
||||
|
||||
|
||||
class Buffered_DatagramReader : protected RingBuffer
|
||||
{
|
||||
inline bool GetMessageFromBuffer(Datagram &inmsg);
|
||||
public:
|
||||
inline Buffered_DatagramReader(int in_size = 8192) ;
|
||||
inline void ReSet(void);
|
||||
//
|
||||
// SOCK_TYPE is used to allow for
|
||||
// abstract socket type to be used ..
|
||||
// see socket_tcp and socket_ssl
|
||||
|
||||
template < class SOCK_TYPE>
|
||||
inline int PumpMessageReader(Datagram &inmsg, SOCK_TYPE &sck)
|
||||
{
|
||||
if(GetMessageFromBuffer(inmsg) == true)
|
||||
return 1;
|
||||
int rp = ReadPump(sck);
|
||||
if(rp == 0)
|
||||
return 0;
|
||||
|
||||
if(rp < 1)
|
||||
return -1;
|
||||
if(GetMessageFromBuffer(inmsg) == true)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
template < class SOCK_TYPE>
|
||||
inline int ReadPump(SOCK_TYPE &sck)
|
||||
{
|
||||
int answer = 0;
|
||||
size_t readsize = BufferAvailabe();
|
||||
|
||||
if(readsize < 1)
|
||||
{
|
||||
Compress();
|
||||
readsize = BufferAvailabe();
|
||||
}
|
||||
|
||||
if(readsize > 0)
|
||||
{
|
||||
char * ff = GetBufferOpen();
|
||||
int gotbytes = sck.RecvData(ff,(int)readsize);
|
||||
if(gotbytes < 0) // some error
|
||||
{
|
||||
int er = GETERROR();
|
||||
if(!sck.ErrorIs_WouldBlocking(gotbytes) )
|
||||
{
|
||||
answer = -3; // hard error ?
|
||||
}
|
||||
else
|
||||
{
|
||||
answer = 0; // try again nothing to read
|
||||
}
|
||||
}
|
||||
else if(gotbytes > 0) // ok got some lets process it
|
||||
{
|
||||
|
||||
_EndPos += gotbytes;
|
||||
answer = 1;
|
||||
}
|
||||
else // 0 mean other end disconect arggggg
|
||||
{
|
||||
answer = -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
answer = -2;
|
||||
}
|
||||
return answer;
|
||||
}
|
||||
};
|
||||
|
||||
#include "buffered_datagramreader.i"
|
||||
|
||||
#endif //__BUFFEREDREADER_GM_H__
|
||||
|
||||
#ifndef __BUFFEREDREADER_GM_H__
|
||||
#define __BUFFEREDREADER_GM_H__
|
||||
|
||||
#include "ringbuffer.h"
|
||||
#include "datagram.h"
|
||||
|
||||
inline unsigned short GetUnsignedShort(char * in)
|
||||
{
|
||||
return *((unsigned short *)in);
|
||||
};
|
||||
|
||||
|
||||
class EXPCL_PANDA Buffered_DatagramReader : protected RingBuffer
|
||||
{
|
||||
inline bool GetMessageFromBuffer(Datagram &inmsg);
|
||||
public:
|
||||
inline Buffered_DatagramReader(int in_size = 8192) ;
|
||||
inline void ReSet(void);
|
||||
//
|
||||
// SOCK_TYPE is used to allow for
|
||||
// abstract socket type to be used ..
|
||||
// see socket_tcp and socket_ssl
|
||||
|
||||
template < class SOCK_TYPE>
|
||||
inline int PumpMessageReader(Datagram &inmsg, SOCK_TYPE &sck)
|
||||
{
|
||||
if(GetMessageFromBuffer(inmsg) == true)
|
||||
return 1;
|
||||
int rp = ReadPump(sck);
|
||||
if(rp == 0)
|
||||
return 0;
|
||||
|
||||
if(rp < 1)
|
||||
return -1;
|
||||
if(GetMessageFromBuffer(inmsg) == true)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
template < class SOCK_TYPE>
|
||||
inline int ReadPump(SOCK_TYPE &sck)
|
||||
{
|
||||
int answer = 0;
|
||||
size_t readsize = BufferAvailabe();
|
||||
|
||||
if(readsize < 1)
|
||||
{
|
||||
Compress();
|
||||
readsize = BufferAvailabe();
|
||||
}
|
||||
|
||||
if(readsize > 0)
|
||||
{
|
||||
char * ff = GetBufferOpen();
|
||||
int gotbytes = sck.RecvData(ff,(int)readsize);
|
||||
if(gotbytes < 0) // some error
|
||||
{
|
||||
int er = GETERROR();
|
||||
if(!sck.ErrorIs_WouldBlocking(gotbytes) )
|
||||
{
|
||||
answer = -3; // hard error ?
|
||||
}
|
||||
else
|
||||
{
|
||||
answer = 0; // try again nothing to read
|
||||
}
|
||||
}
|
||||
else if(gotbytes > 0) // ok got some lets process it
|
||||
{
|
||||
|
||||
_EndPos += gotbytes;
|
||||
answer = 1;
|
||||
}
|
||||
else // 0 mean other end disconect arggggg
|
||||
{
|
||||
answer = -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
answer = -2;
|
||||
}
|
||||
return answer;
|
||||
}
|
||||
};
|
||||
|
||||
#include "buffered_datagramreader.i"
|
||||
|
||||
#endif //__BUFFEREDREADER_GM_H__
|
||||
|
||||
|
|
|
|||
|
|
@ -1,44 +1,44 @@
|
|||
#ifndef __MEMBUFFER_GM_H__
|
||||
#define __MEMBUFFER_GM_H__
|
||||
// RHH
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : GmMemBuf
|
||||
// Description : this a base class designed to be used to for items that will
|
||||
// share portions of a memorty buufer and want to avoid copying the data
|
||||
//
|
||||
// Use if the class wants ot allow for refrence in place of data arrays..
|
||||
// ** be carefull could be dangerous **
|
||||
//
|
||||
// GmCoreMessage
|
||||
// GmRingBuffer
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class MemBuffer
|
||||
{
|
||||
public:
|
||||
inline MemBuffer(void);
|
||||
inline MemBuffer(size_t len);
|
||||
inline MemBuffer(char * data, size_t len);
|
||||
virtual ~MemBuffer();
|
||||
inline void SetBuffer(char * data, size_t len);
|
||||
inline void GrowBuffer(size_t len);
|
||||
inline size_t GetBufferSize(void ) const;
|
||||
inline char * GetBuffer(void);
|
||||
inline const char * GetBuffer(void) const;
|
||||
inline bool InBufferRange(char * );
|
||||
protected:
|
||||
bool _BufferLocal; // indicates responsibility of managment of the data
|
||||
size_t _BufferLen; // the length of the data
|
||||
char * _Buffer; // the data
|
||||
|
||||
inline void ClearBuffer(void);
|
||||
inline void AllocBuffer(size_t len);
|
||||
};
|
||||
|
||||
|
||||
#include "membuffer.i"
|
||||
|
||||
|
||||
#endif //__MEMBUFFER_GM_H__
|
||||
|
||||
#ifndef __MEMBUFFER_GM_H__
|
||||
#define __MEMBUFFER_GM_H__
|
||||
// RHH
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : GmMemBuf
|
||||
// Description : this a base class designed to be used to for items that will
|
||||
// share portions of a memorty buufer and want to avoid copying the data
|
||||
//
|
||||
// Use if the class wants ot allow for refrence in place of data arrays..
|
||||
// ** be carefull could be dangerous **
|
||||
//
|
||||
// GmCoreMessage
|
||||
// GmRingBuffer
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA MemBuffer
|
||||
{
|
||||
public:
|
||||
inline MemBuffer(void);
|
||||
inline MemBuffer(size_t len);
|
||||
inline MemBuffer(char * data, size_t len);
|
||||
virtual ~MemBuffer();
|
||||
inline void SetBuffer(char * data, size_t len);
|
||||
inline void GrowBuffer(size_t len);
|
||||
inline size_t GetBufferSize(void ) const;
|
||||
inline char * GetBuffer(void);
|
||||
inline const char * GetBuffer(void) const;
|
||||
inline bool InBufferRange(char * );
|
||||
protected:
|
||||
bool _BufferLocal; // indicates responsibility of managment of the data
|
||||
size_t _BufferLen; // the length of the data
|
||||
char * _Buffer; // the data
|
||||
|
||||
inline void ClearBuffer(void);
|
||||
inline void AllocBuffer(size_t len);
|
||||
};
|
||||
|
||||
|
||||
#include "membuffer.i"
|
||||
|
||||
|
||||
#endif //__MEMBUFFER_GM_H__
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +0,0 @@
|
|||
#include "socket_base.h"
|
||||
|
||||
|
||||
|
|
@ -1,47 +1,47 @@
|
|||
#ifndef __RINGBUFFER_GM_H__
|
||||
#define __RINGBUFFER_GM_H__
|
||||
////////////////////////////////////////////
|
||||
|
||||
// RHH
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : GmRingBuffer
|
||||
// Description : This is an implemention of the membuffer with ring
|
||||
// buffer interface on it....
|
||||
//
|
||||
// Main target right know is base class for network
|
||||
// stream buffering both input and output
|
||||
//
|
||||
// see BufferedReader_Gm
|
||||
// BufferedWriter_Gm
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
#include "membuffer.h"
|
||||
class RingBuffer : protected MemBuffer
|
||||
{
|
||||
protected:
|
||||
size_t _StartPos;
|
||||
size_t _EndPos;
|
||||
inline char * GetMessageHead(void);
|
||||
inline char * GetBufferOpen(void);
|
||||
inline void ForceWindowSlide(void);
|
||||
#define FastGetMessageHead() (_Buffer+_StartPos)
|
||||
#define FastAmountBeffered() (_EndPos - _StartPos)
|
||||
|
||||
inline bool PutFast(const char * data, size_t len);
|
||||
|
||||
public:
|
||||
inline size_t AmountBuffered(void);
|
||||
inline size_t BufferAvailabe(void);
|
||||
inline void ResetContent(void);
|
||||
|
||||
inline RingBuffer(size_t in_size = 4096);
|
||||
inline void FullCompress(void);
|
||||
inline void Compress(void);
|
||||
inline bool Put(const char * data, size_t len);
|
||||
inline bool Get(char * data, size_t len);
|
||||
};
|
||||
|
||||
#include "ringbuffer.i"
|
||||
|
||||
#endif //__RINGBUFFER_GM_H__
|
||||
|
||||
#ifndef __RINGBUFFER_GM_H__
|
||||
#define __RINGBUFFER_GM_H__
|
||||
////////////////////////////////////////////
|
||||
|
||||
// RHH
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : GmRingBuffer
|
||||
// Description : This is an implemention of the membuffer with ring
|
||||
// buffer interface on it....
|
||||
//
|
||||
// Main target right know is base class for network
|
||||
// stream buffering both input and output
|
||||
//
|
||||
// see BufferedReader_Gm
|
||||
// BufferedWriter_Gm
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
#include "membuffer.h"
|
||||
class EXPCL_PANDA RingBuffer : protected MemBuffer
|
||||
{
|
||||
protected:
|
||||
size_t _StartPos;
|
||||
size_t _EndPos;
|
||||
inline char * GetMessageHead(void);
|
||||
inline char * GetBufferOpen(void);
|
||||
inline void ForceWindowSlide(void);
|
||||
#define FastGetMessageHead() (_Buffer+_StartPos)
|
||||
#define FastAmountBeffered() (_EndPos - _StartPos)
|
||||
|
||||
inline bool PutFast(const char * data, size_t len);
|
||||
|
||||
public:
|
||||
inline size_t AmountBuffered(void);
|
||||
inline size_t BufferAvailabe(void);
|
||||
inline void ResetContent(void);
|
||||
|
||||
inline RingBuffer(size_t in_size = 4096);
|
||||
inline void FullCompress(void);
|
||||
inline void Compress(void);
|
||||
inline bool Put(const char * data, size_t len);
|
||||
inline bool Get(char * data, size_t len);
|
||||
};
|
||||
|
||||
#include "ringbuffer.i"
|
||||
|
||||
#endif //__RINGBUFFER_GM_H__
|
||||
|
||||
|
|
|
|||
|
|
@ -1,287 +1,287 @@
|
|||
#ifndef __SOCKET_ADDRESS_H__
|
||||
#define __SOCKET_ADDRESS_H__
|
||||
|
||||
#include <string>
|
||||
#include "dtoolbase.h"
|
||||
|
||||
///////////////////////////////////
|
||||
// Class : Socket_Address
|
||||
//
|
||||
// Description: A simple place to store and munipulate tcp and port address for
|
||||
// communication layer
|
||||
//
|
||||
//////////////////////////////
|
||||
class Socket_Address
|
||||
{
|
||||
public:
|
||||
typedef struct sockaddr_in AddressType;
|
||||
Socket_Address(const AddressType &inaddr);
|
||||
AddressType & GetAddressInfo() { return _addr; }
|
||||
const AddressType & GetAddressInfo() const { return _addr; }
|
||||
PUBLISHED:
|
||||
|
||||
Socket_Address(short port = 0);
|
||||
Socket_Address(const Socket_Address &inaddr);
|
||||
|
||||
virtual ~Socket_Address();
|
||||
|
||||
bool set_any_IP(int port);
|
||||
bool set_port(int port);
|
||||
bool set_broadcast(int port);
|
||||
|
||||
bool set_host(const std::string &hostname, int port) ;
|
||||
bool set_host(const std::string &hostname) ;
|
||||
bool set_host(unsigned int ip4adr, int port);
|
||||
void clear();
|
||||
|
||||
unsigned short get_port() const;
|
||||
std::string get_ip() const ;
|
||||
std::string get_ip_port() const;
|
||||
unsigned long GetIPAddressRaw() const;
|
||||
|
||||
inline bool operator== (const Socket_Address &in) const;
|
||||
inline bool operator < (const Socket_Address &in) const;
|
||||
|
||||
|
||||
inline bool isMcastRange();
|
||||
|
||||
private:
|
||||
AddressType _addr;
|
||||
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
// Function name : Socket_Address::GetIPAdddressRaw
|
||||
// Description : Return a RAW sockaddr_in
|
||||
//////////////////////////////////////////////////////////////
|
||||
inline unsigned long Socket_Address::GetIPAddressRaw() const
|
||||
{
|
||||
return _addr.sin_addr.s_addr;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
// Function name : Socket_Address
|
||||
// Description : Constructor that lets us set a port value
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline Socket_Address::Socket_Address(short port)
|
||||
{
|
||||
_addr.sin_family = AF_INET;
|
||||
_addr.sin_addr.s_addr = INADDR_ANY;
|
||||
_addr.sin_port = htons(port);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : Socket_Address Constructor
|
||||
// Description : Copy Constructor
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline Socket_Address::Socket_Address(const Socket_Address &inaddr)
|
||||
{
|
||||
_addr.sin_family = inaddr._addr.sin_family;
|
||||
_addr.sin_addr.s_addr = inaddr._addr.sin_addr.s_addr;
|
||||
_addr.sin_port = inaddr._addr.sin_port;
|
||||
}
|
||||
|
||||
inline Socket_Address::Socket_Address(const AddressType &inaddr)
|
||||
{
|
||||
_addr.sin_family = inaddr.sin_family;
|
||||
_addr.sin_addr.s_addr = inaddr.sin_addr.s_addr;
|
||||
_addr.sin_port = inaddr.sin_port;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : ~Socket_Address::Socket_Address
|
||||
// Description : Normal Destructor
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline Socket_Address::~Socket_Address()
|
||||
{}
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
// Function name : Socket_Address::operator==
|
||||
// Description : Allow for normal == operation on a address item..
|
||||
// Will simplify the use in sorted containers..
|
||||
//////////////////////////////////////////////////////////////
|
||||
inline bool Socket_Address::operator==(const Socket_Address &in) const
|
||||
{
|
||||
return ((_addr.sin_family == in._addr.sin_family) &&
|
||||
(_addr.sin_addr.s_addr == in._addr.sin_addr.s_addr) &&
|
||||
(_addr.sin_port == in._addr.sin_port)
|
||||
);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : set_broadcast
|
||||
// Description : Set to the broadcast address and a specified port
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline bool Socket_Address::set_broadcast(int port)
|
||||
{
|
||||
_addr.sin_family = AF_INET;
|
||||
_addr.sin_addr.s_addr = 0xffffffff;
|
||||
_addr.sin_port = htons(port);
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : set_any_IP
|
||||
// Description : Set to any address and a specified port
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline bool Socket_Address::set_any_IP(int port)
|
||||
{
|
||||
_addr.sin_family = AF_INET;
|
||||
_addr.sin_addr.s_addr = INADDR_ANY;
|
||||
_addr.sin_port = htons(port);
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : set_port
|
||||
// Description : Set to a specified port
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline bool Socket_Address::set_port(int port)
|
||||
{
|
||||
_addr.sin_port = htons(port);
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : clear
|
||||
// Description : Set the internal values to a suitable known value
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline void Socket_Address::clear()
|
||||
{
|
||||
_addr.sin_family = AF_INET;
|
||||
_addr.sin_addr.s_addr = INADDR_ANY;
|
||||
_addr.sin_port = htons(0);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : get_port
|
||||
// Description : Get the port portion as an integer
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline unsigned short Socket_Address::get_port() const
|
||||
{
|
||||
return ntohs(_addr.sin_port);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : get_ip
|
||||
// Description : Return the ip address portion in dot notation string
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline std::string Socket_Address::get_ip() const
|
||||
{
|
||||
return std::string(inet_ntoa(_addr.sin_addr));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : get_ip_port
|
||||
// Description : Return the ip address/port in dot notation string
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline std::string Socket_Address::get_ip_port() const
|
||||
{
|
||||
char buf1[100]; // 100 is more than enough for any ip address:port combo..
|
||||
sprintf(buf1, "%s:%d", inet_ntoa(_addr.sin_addr), get_port());
|
||||
return std::string(buf1);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : set_host
|
||||
// Description : this function will take a port and string-based tcp address and initialize
|
||||
// the address with the information
|
||||
//
|
||||
// Return type : bool (address is undefined after an error)
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline bool Socket_Address::set_host(const std::string &hostname, int port)
|
||||
{
|
||||
struct hostent *hp = NULL;
|
||||
|
||||
//
|
||||
// hmm inet_addr does not resolve 255.255.255.255 on ME/98 ??
|
||||
//
|
||||
// * HACK * ??
|
||||
if(hostname == "255.255.255.255")
|
||||
return set_broadcast(port);
|
||||
//
|
||||
//
|
||||
|
||||
UINT32 addr = (long)inet_addr (hostname.c_str());
|
||||
if(addr == INADDR_NONE)
|
||||
{
|
||||
hp = gethostbyname(hostname.c_str());
|
||||
if(hp== NULL)
|
||||
return false;
|
||||
else
|
||||
memcpy(&(_addr.sin_addr),hp->h_addr_list[0] , (unsigned int) hp->h_length);
|
||||
}
|
||||
else
|
||||
(void) memcpy(&_addr.sin_addr,&addr,sizeof(addr));
|
||||
|
||||
_addr.sin_port = htons(port);
|
||||
_addr.sin_family = AF_INET;
|
||||
return true;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
// Function name : Socket_Address::set_host
|
||||
// Description :
|
||||
//////////////////////////////////////////////////////////////
|
||||
inline bool Socket_Address::set_host(const std::string &hostname)
|
||||
{
|
||||
std::string::size_type pos = hostname.find(':');
|
||||
if (pos == std::string::npos)
|
||||
return false;
|
||||
|
||||
std::string host = hostname.substr(0, pos);
|
||||
std::string port = hostname.substr(pos + 1, 100);;
|
||||
|
||||
int port_dig = atoi(port.c_str());
|
||||
|
||||
return set_host(host, port_dig);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
// Function name : Socket_Address::set_host
|
||||
// Description :
|
||||
//////////////////////////////////////////////////////////////
|
||||
inline bool Socket_Address::set_host(UINT32 in_hostname, int port)
|
||||
{
|
||||
memcpy(&_addr.sin_addr, &in_hostname, sizeof(in_hostname));
|
||||
_addr.sin_port = htons(port);
|
||||
_addr.sin_family = AF_INET;
|
||||
return true;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
// Function name : <
|
||||
// Description :
|
||||
//////////////////////////////////////////////////////////////
|
||||
inline bool Socket_Address::operator < (const Socket_Address &in) const
|
||||
{
|
||||
if (_addr.sin_port < in._addr.sin_port)
|
||||
return true;
|
||||
|
||||
if (_addr.sin_port > in._addr.sin_port)
|
||||
return false;
|
||||
|
||||
if (_addr.sin_addr.s_addr < in._addr.sin_addr.s_addr)
|
||||
return true;
|
||||
|
||||
if (_addr.sin_addr.s_addr > in._addr.sin_addr.s_addr)
|
||||
return false;
|
||||
|
||||
|
||||
return (_addr.sin_family < in._addr.sin_family);
|
||||
}
|
||||
//////////////////////////////////////////////////////////////
|
||||
// Function name : isMcastRange
|
||||
// Description : return true if the address is in the mcast range.
|
||||
//////////////////////////////////////////////////////////////
|
||||
inline bool Socket_Address::isMcastRange(void)
|
||||
{
|
||||
UINT32 address = ntohl(_addr.sin_addr.s_addr);
|
||||
//224.0.0.0-239.255.255.255 .. e0,ef
|
||||
if(address >= 0xe0000000 && address < 0xefffffff)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
#endif //__SOCKET_ADDRESS_H__
|
||||
#ifndef __SOCKET_ADDRESS_H__
|
||||
#define __SOCKET_ADDRESS_H__
|
||||
|
||||
#include <string>
|
||||
#include "dtoolbase.h"
|
||||
#include "pandabase.h"
|
||||
///////////////////////////////////
|
||||
// Class : Socket_Address
|
||||
//
|
||||
// Description: A simple place to store and munipulate tcp and port address for
|
||||
// communication layer
|
||||
//
|
||||
//////////////////////////////
|
||||
class EXPCL_PANDA Socket_Address
|
||||
{
|
||||
public:
|
||||
typedef struct sockaddr_in AddressType;
|
||||
Socket_Address(const AddressType &inaddr);
|
||||
AddressType & GetAddressInfo() { return _addr; }
|
||||
const AddressType & GetAddressInfo() const { return _addr; }
|
||||
PUBLISHED:
|
||||
|
||||
Socket_Address(short port = 0);
|
||||
Socket_Address(const Socket_Address &inaddr);
|
||||
|
||||
virtual ~Socket_Address();
|
||||
|
||||
bool set_any_IP(int port);
|
||||
bool set_port(int port);
|
||||
bool set_broadcast(int port);
|
||||
|
||||
bool set_host(const std::string &hostname, int port) ;
|
||||
bool set_host(const std::string &hostname) ;
|
||||
bool set_host(unsigned int ip4adr, int port);
|
||||
void clear();
|
||||
|
||||
unsigned short get_port() const;
|
||||
std::string get_ip() const ;
|
||||
std::string get_ip_port() const;
|
||||
unsigned long GetIPAddressRaw() const;
|
||||
|
||||
inline bool operator== (const Socket_Address &in) const;
|
||||
inline bool operator < (const Socket_Address &in) const;
|
||||
|
||||
|
||||
inline bool isMcastRange();
|
||||
|
||||
private:
|
||||
AddressType _addr;
|
||||
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
// Function name : Socket_Address::GetIPAdddressRaw
|
||||
// Description : Return a RAW sockaddr_in
|
||||
//////////////////////////////////////////////////////////////
|
||||
inline unsigned long Socket_Address::GetIPAddressRaw() const
|
||||
{
|
||||
return _addr.sin_addr.s_addr;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
// Function name : Socket_Address
|
||||
// Description : Constructor that lets us set a port value
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline Socket_Address::Socket_Address(short port)
|
||||
{
|
||||
_addr.sin_family = AF_INET;
|
||||
_addr.sin_addr.s_addr = INADDR_ANY;
|
||||
_addr.sin_port = htons(port);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : Socket_Address Constructor
|
||||
// Description : Copy Constructor
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline Socket_Address::Socket_Address(const Socket_Address &inaddr)
|
||||
{
|
||||
_addr.sin_family = inaddr._addr.sin_family;
|
||||
_addr.sin_addr.s_addr = inaddr._addr.sin_addr.s_addr;
|
||||
_addr.sin_port = inaddr._addr.sin_port;
|
||||
}
|
||||
|
||||
inline Socket_Address::Socket_Address(const AddressType &inaddr)
|
||||
{
|
||||
_addr.sin_family = inaddr.sin_family;
|
||||
_addr.sin_addr.s_addr = inaddr.sin_addr.s_addr;
|
||||
_addr.sin_port = inaddr.sin_port;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : ~Socket_Address::Socket_Address
|
||||
// Description : Normal Destructor
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline Socket_Address::~Socket_Address()
|
||||
{}
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
// Function name : Socket_Address::operator==
|
||||
// Description : Allow for normal == operation on a address item..
|
||||
// Will simplify the use in sorted containers..
|
||||
//////////////////////////////////////////////////////////////
|
||||
inline bool Socket_Address::operator==(const Socket_Address &in) const
|
||||
{
|
||||
return ((_addr.sin_family == in._addr.sin_family) &&
|
||||
(_addr.sin_addr.s_addr == in._addr.sin_addr.s_addr) &&
|
||||
(_addr.sin_port == in._addr.sin_port)
|
||||
);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : set_broadcast
|
||||
// Description : Set to the broadcast address and a specified port
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline bool Socket_Address::set_broadcast(int port)
|
||||
{
|
||||
_addr.sin_family = AF_INET;
|
||||
_addr.sin_addr.s_addr = 0xffffffff;
|
||||
_addr.sin_port = htons(port);
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : set_any_IP
|
||||
// Description : Set to any address and a specified port
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline bool Socket_Address::set_any_IP(int port)
|
||||
{
|
||||
_addr.sin_family = AF_INET;
|
||||
_addr.sin_addr.s_addr = INADDR_ANY;
|
||||
_addr.sin_port = htons(port);
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : set_port
|
||||
// Description : Set to a specified port
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline bool Socket_Address::set_port(int port)
|
||||
{
|
||||
_addr.sin_port = htons(port);
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : clear
|
||||
// Description : Set the internal values to a suitable known value
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline void Socket_Address::clear()
|
||||
{
|
||||
_addr.sin_family = AF_INET;
|
||||
_addr.sin_addr.s_addr = INADDR_ANY;
|
||||
_addr.sin_port = htons(0);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : get_port
|
||||
// Description : Get the port portion as an integer
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline unsigned short Socket_Address::get_port() const
|
||||
{
|
||||
return ntohs(_addr.sin_port);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : get_ip
|
||||
// Description : Return the ip address portion in dot notation string
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline std::string Socket_Address::get_ip() const
|
||||
{
|
||||
return std::string(inet_ntoa(_addr.sin_addr));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : get_ip_port
|
||||
// Description : Return the ip address/port in dot notation string
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline std::string Socket_Address::get_ip_port() const
|
||||
{
|
||||
char buf1[100]; // 100 is more than enough for any ip address:port combo..
|
||||
sprintf(buf1, "%s:%d", inet_ntoa(_addr.sin_addr), get_port());
|
||||
return std::string(buf1);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : set_host
|
||||
// Description : this function will take a port and string-based tcp address and initialize
|
||||
// the address with the information
|
||||
//
|
||||
// Return type : bool (address is undefined after an error)
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline bool Socket_Address::set_host(const std::string &hostname, int port)
|
||||
{
|
||||
struct hostent *hp = NULL;
|
||||
|
||||
//
|
||||
// hmm inet_addr does not resolve 255.255.255.255 on ME/98 ??
|
||||
//
|
||||
// * HACK * ??
|
||||
if(hostname == "255.255.255.255")
|
||||
return set_broadcast(port);
|
||||
//
|
||||
//
|
||||
|
||||
UINT32 addr = (long)inet_addr (hostname.c_str());
|
||||
if(addr == INADDR_NONE)
|
||||
{
|
||||
hp = gethostbyname(hostname.c_str());
|
||||
if(hp== NULL)
|
||||
return false;
|
||||
else
|
||||
memcpy(&(_addr.sin_addr),hp->h_addr_list[0] , (unsigned int) hp->h_length);
|
||||
}
|
||||
else
|
||||
(void) memcpy(&_addr.sin_addr,&addr,sizeof(addr));
|
||||
|
||||
_addr.sin_port = htons(port);
|
||||
_addr.sin_family = AF_INET;
|
||||
return true;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
// Function name : Socket_Address::set_host
|
||||
// Description :
|
||||
//////////////////////////////////////////////////////////////
|
||||
inline bool Socket_Address::set_host(const std::string &hostname)
|
||||
{
|
||||
std::string::size_type pos = hostname.find(':');
|
||||
if (pos == std::string::npos)
|
||||
return false;
|
||||
|
||||
std::string host = hostname.substr(0, pos);
|
||||
std::string port = hostname.substr(pos + 1, 100);;
|
||||
|
||||
int port_dig = atoi(port.c_str());
|
||||
|
||||
return set_host(host, port_dig);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
// Function name : Socket_Address::set_host
|
||||
// Description :
|
||||
//////////////////////////////////////////////////////////////
|
||||
inline bool Socket_Address::set_host(UINT32 in_hostname, int port)
|
||||
{
|
||||
memcpy(&_addr.sin_addr, &in_hostname, sizeof(in_hostname));
|
||||
_addr.sin_port = htons(port);
|
||||
_addr.sin_family = AF_INET;
|
||||
return true;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
// Function name : <
|
||||
// Description :
|
||||
//////////////////////////////////////////////////////////////
|
||||
inline bool Socket_Address::operator < (const Socket_Address &in) const
|
||||
{
|
||||
if (_addr.sin_port < in._addr.sin_port)
|
||||
return true;
|
||||
|
||||
if (_addr.sin_port > in._addr.sin_port)
|
||||
return false;
|
||||
|
||||
if (_addr.sin_addr.s_addr < in._addr.sin_addr.s_addr)
|
||||
return true;
|
||||
|
||||
if (_addr.sin_addr.s_addr > in._addr.sin_addr.s_addr)
|
||||
return false;
|
||||
|
||||
|
||||
return (_addr.sin_family < in._addr.sin_family);
|
||||
}
|
||||
//////////////////////////////////////////////////////////////
|
||||
// Function name : isMcastRange
|
||||
// Description : return true if the address is in the mcast range.
|
||||
//////////////////////////////////////////////////////////////
|
||||
inline bool Socket_Address::isMcastRange(void)
|
||||
{
|
||||
UINT32 address = ntohl(_addr.sin_addr.s_addr);
|
||||
//224.0.0.0-239.255.255.255 .. e0,ef
|
||||
if(address >= 0xe0000000 && address < 0xefffffff)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
#endif //__SOCKET_ADDRESS_H__
|
||||
|
|
|
|||
|
|
@ -1,247 +1,247 @@
|
|||
#ifndef __SOCKET_IP_H__
|
||||
#define __SOCKET_IP_H__
|
||||
|
||||
// forward declarations for friends...
|
||||
class Socket_TCP;
|
||||
class Socket_UDP;
|
||||
class Socket_TCP_Listen;
|
||||
class Socket_UDP_Incoming;
|
||||
class Socket_UDP_Outgoing;
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
// Class : Socket_IP
|
||||
//
|
||||
// Description : Base functionality for a INET domain Socket
|
||||
// this call should be the starting point for all other
|
||||
// unix domain sockets
|
||||
//
|
||||
//
|
||||
// SocketIP
|
||||
// |
|
||||
// -------------------------------------------------------------------
|
||||
// | | | |
|
||||
// SocketTCP SocketTCP_Listen SocketUDP_Incoming SocketUDP_OutBound
|
||||
//
|
||||
//
|
||||
//
|
||||
// socket_fdset
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
class Socket_IP
|
||||
{
|
||||
public:
|
||||
PUBLISHED:
|
||||
|
||||
inline Socket_IP();
|
||||
inline Socket_IP(SOCKET in);
|
||||
virtual ~Socket_IP();
|
||||
|
||||
inline void Close();
|
||||
inline static int GetLastError();
|
||||
inline int SetNonBlocking();
|
||||
inline int SetBlocking();
|
||||
inline bool SetReuseAddress();
|
||||
inline bool Active();
|
||||
inline int SetRecvBufferSize(int size);
|
||||
inline void SetSocket(SOCKET ins);
|
||||
inline SOCKET GetSocket();
|
||||
inline SOCKET GetSocket() const;
|
||||
inline Socket_Address GetPeerName(void) const;
|
||||
|
||||
|
||||
inline static int InitNetworkDriver() { return init_network(); };
|
||||
|
||||
public:
|
||||
private:
|
||||
inline bool ErrorClose();
|
||||
|
||||
SOCKET _socket; // see socket_portable.h
|
||||
|
||||
friend class Socket_TCP;
|
||||
friend class Socket_UDP;
|
||||
friend class Socket_TCP_Listen;
|
||||
friend class Socket_UDP_Incoming;
|
||||
friend class Socket_UDP_Outgoing;
|
||||
friend class Socket_TCP_SSL;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : Socket_IP::ErrorClose
|
||||
// Description : Used by internal to force a close
|
||||
// note that it always returns a false
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline bool Socket_IP::ErrorClose()
|
||||
{
|
||||
if (Active())
|
||||
DO_CLOSE(_socket);
|
||||
_socket = BAD_SOCKET;
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : Socket_IP::Active
|
||||
// Description : Ask if the socket is open (allocated)
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline bool Socket_IP::Active()
|
||||
{
|
||||
return (_socket != BAD_SOCKET);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : Socket_IP::Socket_IP
|
||||
// Description : Def Constructor
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline Socket_IP::Socket_IP()
|
||||
{
|
||||
_socket = BAD_SOCKET;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : Socket_IP::SetSocket
|
||||
// Description : Assigns an existing socket to this class
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline Socket_IP::Socket_IP(SOCKET ins)
|
||||
{
|
||||
_socket = ins;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : Socket_IP::~Socket_IP
|
||||
// Description : Destructor
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline Socket_IP::~Socket_IP()
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : Socket_IP::Close
|
||||
// Description : closes a socket if it is open (allocated)
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline void Socket_IP::Close()
|
||||
{
|
||||
if (Active())
|
||||
DO_CLOSE(_socket);
|
||||
_socket = BAD_SOCKET;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : Socket_IP::GetLastError
|
||||
// Description : gets the last errcode from a socket operation
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline int Socket_IP::GetLastError()
|
||||
{
|
||||
return GETERROR();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : Socket_IP::SetSocket
|
||||
// Description : Assigns an existing socket to this class
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline void Socket_IP::SetSocket(SOCKET ins)
|
||||
{
|
||||
Close();
|
||||
_socket = ins;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : Socket_IP::SetRecvBufferSize
|
||||
// Description : Ok it sets the recv buffer size for both tcp and UDP
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int Socket_IP::SetRecvBufferSize(int insize)
|
||||
{
|
||||
if (setsockopt(_socket, (int) SOL_SOCKET, (int) SO_RCVBUF, (char *) &insize, sizeof(int)))
|
||||
return BASIC_ERROR;
|
||||
|
||||
return ALL_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : SetNonBlocking
|
||||
// Description : this function will throw a socket into non-blocking mode
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline int Socket_IP::SetNonBlocking()
|
||||
{
|
||||
#ifdef BSDBLOCK
|
||||
|
||||
int flags = fcntl(_socket, F_GETFL, 0);
|
||||
flags = flags | O_NONBLOCK;
|
||||
fcntl(_socket, F_SETFL, flags);
|
||||
return ALL_OK;
|
||||
#else
|
||||
unsigned long val = LOCAL_NONBLOCK;
|
||||
unsigned lanswer = 0;
|
||||
lanswer = SOCKIOCTL(_socket, LOCAL_FL_SET, &val);
|
||||
if (lanswer != 0)
|
||||
return BASIC_ERROR;
|
||||
return ALL_OK;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : Socket_IP::SetBlocking
|
||||
// Description : Set the socket to block on subsequent calls to
|
||||
// socket functions that address this socket
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline int Socket_IP::SetBlocking()
|
||||
{
|
||||
#ifdef BSDBLOCK
|
||||
int flags = fcntl(_socket, F_GETFL, 0);
|
||||
flags &= ~O_NONBLOCK;
|
||||
fcntl(_socket, F_SETFL, flags);
|
||||
return ALL_OK;
|
||||
#else
|
||||
unsigned long val = 0;
|
||||
unsigned lanswer = 0;
|
||||
lanswer = SOCKIOCTL(_socket, LOCAL_FL_SET, &val);
|
||||
if (lanswer != 0)
|
||||
return BASIC_ERROR;
|
||||
return ALL_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : SetReuseAddress
|
||||
// Description : Informs a socket to reuse IP address as needed
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline bool Socket_IP::SetReuseAddress()
|
||||
{
|
||||
int bOption = 1;
|
||||
if (setsockopt(_socket, SOL_SOCKET, SO_REUSEADDR, (const char *)&bOption, sizeof(bOption)) != 0)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : Socket_IP::GetSocket
|
||||
// Description : Gets the base socket type
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline SOCKET Socket_IP::GetSocket()
|
||||
{
|
||||
return _socket;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
// Function name : Socket_IP::GetSocket
|
||||
// Description : Get The RAW file id of the socket
|
||||
//////////////////////////////////////////////////////////////
|
||||
inline SOCKET Socket_IP::GetSocket() const
|
||||
{
|
||||
return _socket;
|
||||
}
|
||||
//////////////////////////////////////////////////////////////
|
||||
// Function name : Socket_IP::GetPeerName
|
||||
// Description : Wrapper on berkly getpeername...
|
||||
//////////////////////////////////////////////////////////////
|
||||
inline Socket_Address Socket_IP::GetPeerName(void) const
|
||||
{
|
||||
sockaddr_in name;
|
||||
socklen_t name_len = sizeof(name);
|
||||
memset(&name,0,name_len);
|
||||
|
||||
getpeername(_socket,(sockaddr * )&name,&name_len);
|
||||
return Socket_Address(name);
|
||||
}
|
||||
|
||||
|
||||
#endif //__SOCKET_IP_H__
|
||||
#ifndef __SOCKET_IP_H__
|
||||
#define __SOCKET_IP_H__
|
||||
|
||||
// forward declarations for friends...
|
||||
class Socket_TCP;
|
||||
class Socket_UDP;
|
||||
class Socket_TCP_Listen;
|
||||
class Socket_UDP_Incoming;
|
||||
class Socket_UDP_Outgoing;
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
// Class : Socket_IP
|
||||
//
|
||||
// Description : Base functionality for a INET domain Socket
|
||||
// this call should be the starting point for all other
|
||||
// unix domain sockets
|
||||
//
|
||||
//
|
||||
// SocketIP
|
||||
// |
|
||||
// -------------------------------------------------------------------
|
||||
// | | | |
|
||||
// SocketTCP SocketTCP_Listen SocketUDP_Incoming SocketUDP_OutBound
|
||||
//
|
||||
//
|
||||
//
|
||||
// socket_fdset
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA Socket_IP
|
||||
{
|
||||
public:
|
||||
PUBLISHED:
|
||||
|
||||
inline Socket_IP();
|
||||
inline Socket_IP(SOCKET in);
|
||||
virtual ~Socket_IP();
|
||||
|
||||
inline void Close();
|
||||
inline static int GetLastError();
|
||||
inline int SetNonBlocking();
|
||||
inline int SetBlocking();
|
||||
inline bool SetReuseAddress();
|
||||
inline bool Active();
|
||||
inline int SetRecvBufferSize(int size);
|
||||
inline void SetSocket(SOCKET ins);
|
||||
inline SOCKET GetSocket();
|
||||
inline SOCKET GetSocket() const;
|
||||
inline Socket_Address GetPeerName(void) const;
|
||||
|
||||
|
||||
inline static int InitNetworkDriver() { return init_network(); };
|
||||
|
||||
public:
|
||||
private:
|
||||
inline bool ErrorClose();
|
||||
|
||||
SOCKET _socket; // see socket_portable.h
|
||||
|
||||
friend class Socket_TCP;
|
||||
friend class Socket_UDP;
|
||||
friend class Socket_TCP_Listen;
|
||||
friend class Socket_UDP_Incoming;
|
||||
friend class Socket_UDP_Outgoing;
|
||||
friend class Socket_TCP_SSL;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : Socket_IP::ErrorClose
|
||||
// Description : Used by internal to force a close
|
||||
// note that it always returns a false
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline bool Socket_IP::ErrorClose()
|
||||
{
|
||||
if (Active())
|
||||
DO_CLOSE(_socket);
|
||||
_socket = BAD_SOCKET;
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : Socket_IP::Active
|
||||
// Description : Ask if the socket is open (allocated)
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline bool Socket_IP::Active()
|
||||
{
|
||||
return (_socket != BAD_SOCKET);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : Socket_IP::Socket_IP
|
||||
// Description : Def Constructor
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline Socket_IP::Socket_IP()
|
||||
{
|
||||
_socket = BAD_SOCKET;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : Socket_IP::SetSocket
|
||||
// Description : Assigns an existing socket to this class
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline Socket_IP::Socket_IP(SOCKET ins)
|
||||
{
|
||||
_socket = ins;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : Socket_IP::~Socket_IP
|
||||
// Description : Destructor
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline Socket_IP::~Socket_IP()
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : Socket_IP::Close
|
||||
// Description : closes a socket if it is open (allocated)
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline void Socket_IP::Close()
|
||||
{
|
||||
if (Active())
|
||||
DO_CLOSE(_socket);
|
||||
_socket = BAD_SOCKET;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : Socket_IP::GetLastError
|
||||
// Description : gets the last errcode from a socket operation
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline int Socket_IP::GetLastError()
|
||||
{
|
||||
return GETERROR();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : Socket_IP::SetSocket
|
||||
// Description : Assigns an existing socket to this class
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline void Socket_IP::SetSocket(SOCKET ins)
|
||||
{
|
||||
Close();
|
||||
_socket = ins;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : Socket_IP::SetRecvBufferSize
|
||||
// Description : Ok it sets the recv buffer size for both tcp and UDP
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int Socket_IP::SetRecvBufferSize(int insize)
|
||||
{
|
||||
if (setsockopt(_socket, (int) SOL_SOCKET, (int) SO_RCVBUF, (char *) &insize, sizeof(int)))
|
||||
return BASIC_ERROR;
|
||||
|
||||
return ALL_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : SetNonBlocking
|
||||
// Description : this function will throw a socket into non-blocking mode
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline int Socket_IP::SetNonBlocking()
|
||||
{
|
||||
#ifdef BSDBLOCK
|
||||
|
||||
int flags = fcntl(_socket, F_GETFL, 0);
|
||||
flags = flags | O_NONBLOCK;
|
||||
fcntl(_socket, F_SETFL, flags);
|
||||
return ALL_OK;
|
||||
#else
|
||||
unsigned long val = LOCAL_NONBLOCK;
|
||||
unsigned lanswer = 0;
|
||||
lanswer = SOCKIOCTL(_socket, LOCAL_FL_SET, &val);
|
||||
if (lanswer != 0)
|
||||
return BASIC_ERROR;
|
||||
return ALL_OK;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : Socket_IP::SetBlocking
|
||||
// Description : Set the socket to block on subsequent calls to
|
||||
// socket functions that address this socket
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline int Socket_IP::SetBlocking()
|
||||
{
|
||||
#ifdef BSDBLOCK
|
||||
int flags = fcntl(_socket, F_GETFL, 0);
|
||||
flags &= ~O_NONBLOCK;
|
||||
fcntl(_socket, F_SETFL, flags);
|
||||
return ALL_OK;
|
||||
#else
|
||||
unsigned long val = 0;
|
||||
unsigned lanswer = 0;
|
||||
lanswer = SOCKIOCTL(_socket, LOCAL_FL_SET, &val);
|
||||
if (lanswer != 0)
|
||||
return BASIC_ERROR;
|
||||
return ALL_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : SetReuseAddress
|
||||
// Description : Informs a socket to reuse IP address as needed
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline bool Socket_IP::SetReuseAddress()
|
||||
{
|
||||
int bOption = 1;
|
||||
if (setsockopt(_socket, SOL_SOCKET, SO_REUSEADDR, (const char *)&bOption, sizeof(bOption)) != 0)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : Socket_IP::GetSocket
|
||||
// Description : Gets the base socket type
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline SOCKET Socket_IP::GetSocket()
|
||||
{
|
||||
return _socket;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
// Function name : Socket_IP::GetSocket
|
||||
// Description : Get The RAW file id of the socket
|
||||
//////////////////////////////////////////////////////////////
|
||||
inline SOCKET Socket_IP::GetSocket() const
|
||||
{
|
||||
return _socket;
|
||||
}
|
||||
//////////////////////////////////////////////////////////////
|
||||
// Function name : Socket_IP::GetPeerName
|
||||
// Description : Wrapper on berkly getpeername...
|
||||
//////////////////////////////////////////////////////////////
|
||||
inline Socket_Address Socket_IP::GetPeerName(void) const
|
||||
{
|
||||
sockaddr_in name;
|
||||
socklen_t name_len = sizeof(name);
|
||||
memset(&name,0,name_len);
|
||||
|
||||
getpeername(_socket,(sockaddr * )&name,&name_len);
|
||||
return Socket_Address(name);
|
||||
}
|
||||
|
||||
|
||||
#endif //__SOCKET_IP_H__
|
||||
|
|
|
|||
|
|
@ -1,223 +1,223 @@
|
|||
#ifndef __SOCKET_TCP_H__
|
||||
#define __SOCKET_TCP_H__
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
// Class : Socket_TCP
|
||||
//
|
||||
// Description : Base functionality for a TCP connected socket
|
||||
// This class is pretty useless by itself but it does hide some of the
|
||||
// platform differences from machine to machine
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
class Socket_TCP : public Socket_IP
|
||||
{
|
||||
public:
|
||||
PUBLISHED:
|
||||
inline Socket_TCP(SOCKET);
|
||||
inline Socket_TCP() { };
|
||||
inline int SetNoDelay();
|
||||
inline int SetLinger(int interval_seconds = 0);
|
||||
inline int DontLinger();
|
||||
inline int SetSendBufferSize(int insize);
|
||||
inline bool ActiveOpen(const Socket_Address & theaddress);
|
||||
inline bool ActiveOpenNonBlocking(const Socket_Address & theaddress);
|
||||
inline bool ErrorIs_WouldBlocking(int err);
|
||||
inline bool ShutdownSend();
|
||||
inline int SendData(const std::string &str);
|
||||
// inline int RecvData( std::string &str, int max_len);
|
||||
|
||||
std::string RecvData(int max_len);
|
||||
public:
|
||||
inline int SendData(const char * data, int size);
|
||||
inline int RecvData(char * data, int size);
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
// Function name : Socket_TCP::Socket_TCP
|
||||
// Description :
|
||||
//////////////////////////////////////////////////////////////
|
||||
inline Socket_TCP::Socket_TCP(SOCKET sck) : ::Socket_IP(sck)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : SetNoDelay
|
||||
// Description : Disable Nagle algorithm. Don't delay send to coalesce packets
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline int Socket_TCP::SetNoDelay()
|
||||
{
|
||||
int nodel = 1;
|
||||
int ret1;
|
||||
ret1 = setsockopt(_socket, IPPROTO_TCP, TCP_NODELAY, (char *) & nodel, sizeof(nodel));
|
||||
|
||||
if (ret1 != 0)
|
||||
return BASIC_ERROR;
|
||||
|
||||
return ALL_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : SetLinger
|
||||
// Description : will control the behavior of SO_LINGER for a TCP socket
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int Socket_TCP::SetLinger(int interval_seconds)
|
||||
{
|
||||
linger ll;
|
||||
ll.l_linger = interval_seconds;
|
||||
ll.l_onoff = 1;
|
||||
int ret1 = setsockopt(_socket, SOL_SOCKET, SO_LINGER, (const char *) & ll, sizeof(linger));
|
||||
if (ret1 != 0)
|
||||
return BASIC_ERROR;
|
||||
return ALL_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : Socket_TCP::DontLinger
|
||||
// Description : Turn off the linger flag. The socket will quickly release
|
||||
// buffered items and free up OS resources. You may lose
|
||||
// a stream if you use this flag and do not negotiate the close
|
||||
// at the application layer.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int Socket_TCP::DontLinger()
|
||||
{
|
||||
linger ll;
|
||||
ll.l_linger = 0;
|
||||
ll.l_onoff = 0;
|
||||
int ret1 = setsockopt(_socket, SOL_SOCKET, SO_LINGER, (const char *) & ll, sizeof(linger));
|
||||
if (ret1 != 0)
|
||||
return BASIC_ERROR;
|
||||
return ALL_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : SetSendBufferSize
|
||||
// Description : Just like it sounds. Sets a buffered socket recv buffer size.
|
||||
// This function does not refuse ranges outside hard-coded OS
|
||||
// limits
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int Socket_TCP::SetSendBufferSize(int insize)
|
||||
{
|
||||
if (setsockopt(_socket, (int) SOL_SOCKET, (int) SO_SNDBUF, (char *) &insize, sizeof(int)))
|
||||
return BASIC_ERROR;
|
||||
return ALL_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : ActiveOpen
|
||||
// Description : This function will try and set the socket up for active open to a specified
|
||||
// address and port provided by the input parameter
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool Socket_TCP::ActiveOpen(const Socket_Address & theaddress)
|
||||
{
|
||||
_socket = DO_NEWTCP();
|
||||
if (_socket == BAD_SOCKET)
|
||||
return false;
|
||||
|
||||
if (DO_CONNECT(_socket, &theaddress.GetAddressInfo()) != 0)
|
||||
return ErrorClose();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : ActiveOpenNonBlocking
|
||||
// Description : This function will try and set the socket up for active open to a specified
|
||||
// address and port provided by the input parameter (non-blocking version)
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool Socket_TCP::ActiveOpenNonBlocking(const Socket_Address & theaddress)
|
||||
{
|
||||
_socket = DO_NEWTCP();
|
||||
if (_socket == BAD_SOCKET)
|
||||
return false;
|
||||
|
||||
SetNonBlocking();
|
||||
SetReuseAddress();
|
||||
|
||||
if (DO_CONNECT(_socket, &theaddress.GetAddressInfo()) != 0)
|
||||
if (GETERROR() != LOCAL_CONNECT_BLOCKING)
|
||||
{
|
||||
printf(" None Blockign Connect Error %d",GETERROR());
|
||||
return ErrorClose();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : Socket_TCP::SendData
|
||||
// Description : Ok Lets Send the Data
|
||||
//
|
||||
// Return type : int
|
||||
// - if error
|
||||
// 0 if socket closed for write or lengh is 0
|
||||
// + bytes writen ( May be smaller than requested)
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline int Socket_TCP::SendData(const char * data, int size)
|
||||
{
|
||||
return DO_SOCKET_WRITE(_socket, data, size);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : Socket_TCP::RecvData
|
||||
// Description : Read the data from the connection
|
||||
//
|
||||
// Return type : int
|
||||
// - if error
|
||||
// 0 if socket closed for read or length is 0
|
||||
// + bytes read ( May be smaller than requested)
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline int Socket_TCP::RecvData(char * data, int len)
|
||||
{
|
||||
int ecode = DO_SOCKET_READ(_socket, data, len);
|
||||
return ecode;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : Socket_TCP::RecvData
|
||||
// Description : Read the data from the connection
|
||||
//
|
||||
// Return type : int
|
||||
// - if error
|
||||
// 0 if socket closed for read or length is 0
|
||||
// + bytes read ( May be smaller than requested)
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline std::string Socket_TCP::RecvData(int max_len)
|
||||
{
|
||||
std::string str;
|
||||
char *buffer = (char *) malloc(max_len+1);
|
||||
int ecode = RecvData(buffer,max_len);
|
||||
if(ecode > 0)
|
||||
str.assign(buffer,ecode);
|
||||
|
||||
free(buffer);
|
||||
return str;
|
||||
};
|
||||
|
||||
|
||||
inline bool Socket_TCP::ErrorIs_WouldBlocking(int err)
|
||||
{
|
||||
return (GETERROR() == LOCAL_BLOCKING_ERROR);
|
||||
}
|
||||
|
||||
inline bool Socket_TCP::ShutdownSend()
|
||||
{
|
||||
return do_shutdown_send(_socket);
|
||||
};
|
||||
|
||||
/*
|
||||
inline bool Socket_TCP::DoNotLinger()
|
||||
{
|
||||
int bOption = 1;
|
||||
if (setsockopt(_socket, SOL_SOCKET, SO_DONTLINGER, (const char *)&bOption, sizeof(bOption)) != 0)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
*/
|
||||
|
||||
inline int Socket_TCP::SendData(const std::string &str)
|
||||
{
|
||||
return SendData(str.data(), str.size());
|
||||
};
|
||||
|
||||
#endif //__SOCKET_TCP_H__
|
||||
#ifndef __SOCKET_TCP_H__
|
||||
#define __SOCKET_TCP_H__
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
// Class : Socket_TCP
|
||||
//
|
||||
// Description : Base functionality for a TCP connected socket
|
||||
// This class is pretty useless by itself but it does hide some of the
|
||||
// platform differences from machine to machine
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA Socket_TCP : public Socket_IP
|
||||
{
|
||||
public:
|
||||
PUBLISHED:
|
||||
inline Socket_TCP(SOCKET);
|
||||
inline Socket_TCP() { };
|
||||
inline int SetNoDelay();
|
||||
inline int SetLinger(int interval_seconds = 0);
|
||||
inline int DontLinger();
|
||||
inline int SetSendBufferSize(int insize);
|
||||
inline bool ActiveOpen(const Socket_Address & theaddress);
|
||||
inline bool ActiveOpenNonBlocking(const Socket_Address & theaddress);
|
||||
inline bool ErrorIs_WouldBlocking(int err);
|
||||
inline bool ShutdownSend();
|
||||
inline int SendData(const std::string &str);
|
||||
// inline int RecvData( std::string &str, int max_len);
|
||||
|
||||
std::string RecvData(int max_len);
|
||||
public:
|
||||
inline int SendData(const char * data, int size);
|
||||
inline int RecvData(char * data, int size);
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
// Function name : Socket_TCP::Socket_TCP
|
||||
// Description :
|
||||
//////////////////////////////////////////////////////////////
|
||||
inline Socket_TCP::Socket_TCP(SOCKET sck) : ::Socket_IP(sck)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : SetNoDelay
|
||||
// Description : Disable Nagle algorithm. Don't delay send to coalesce packets
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline int Socket_TCP::SetNoDelay()
|
||||
{
|
||||
int nodel = 1;
|
||||
int ret1;
|
||||
ret1 = setsockopt(_socket, IPPROTO_TCP, TCP_NODELAY, (char *) & nodel, sizeof(nodel));
|
||||
|
||||
if (ret1 != 0)
|
||||
return BASIC_ERROR;
|
||||
|
||||
return ALL_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : SetLinger
|
||||
// Description : will control the behavior of SO_LINGER for a TCP socket
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int Socket_TCP::SetLinger(int interval_seconds)
|
||||
{
|
||||
linger ll;
|
||||
ll.l_linger = interval_seconds;
|
||||
ll.l_onoff = 1;
|
||||
int ret1 = setsockopt(_socket, SOL_SOCKET, SO_LINGER, (const char *) & ll, sizeof(linger));
|
||||
if (ret1 != 0)
|
||||
return BASIC_ERROR;
|
||||
return ALL_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : Socket_TCP::DontLinger
|
||||
// Description : Turn off the linger flag. The socket will quickly release
|
||||
// buffered items and free up OS resources. You may lose
|
||||
// a stream if you use this flag and do not negotiate the close
|
||||
// at the application layer.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int Socket_TCP::DontLinger()
|
||||
{
|
||||
linger ll;
|
||||
ll.l_linger = 0;
|
||||
ll.l_onoff = 0;
|
||||
int ret1 = setsockopt(_socket, SOL_SOCKET, SO_LINGER, (const char *) & ll, sizeof(linger));
|
||||
if (ret1 != 0)
|
||||
return BASIC_ERROR;
|
||||
return ALL_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : SetSendBufferSize
|
||||
// Description : Just like it sounds. Sets a buffered socket recv buffer size.
|
||||
// This function does not refuse ranges outside hard-coded OS
|
||||
// limits
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int Socket_TCP::SetSendBufferSize(int insize)
|
||||
{
|
||||
if (setsockopt(_socket, (int) SOL_SOCKET, (int) SO_SNDBUF, (char *) &insize, sizeof(int)))
|
||||
return BASIC_ERROR;
|
||||
return ALL_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : ActiveOpen
|
||||
// Description : This function will try and set the socket up for active open to a specified
|
||||
// address and port provided by the input parameter
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool Socket_TCP::ActiveOpen(const Socket_Address & theaddress)
|
||||
{
|
||||
_socket = DO_NEWTCP();
|
||||
if (_socket == BAD_SOCKET)
|
||||
return false;
|
||||
|
||||
if (DO_CONNECT(_socket, &theaddress.GetAddressInfo()) != 0)
|
||||
return ErrorClose();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : ActiveOpenNonBlocking
|
||||
// Description : This function will try and set the socket up for active open to a specified
|
||||
// address and port provided by the input parameter (non-blocking version)
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool Socket_TCP::ActiveOpenNonBlocking(const Socket_Address & theaddress)
|
||||
{
|
||||
_socket = DO_NEWTCP();
|
||||
if (_socket == BAD_SOCKET)
|
||||
return false;
|
||||
|
||||
SetNonBlocking();
|
||||
SetReuseAddress();
|
||||
|
||||
if (DO_CONNECT(_socket, &theaddress.GetAddressInfo()) != 0)
|
||||
if (GETERROR() != LOCAL_CONNECT_BLOCKING)
|
||||
{
|
||||
printf(" None Blockign Connect Error %d",GETERROR());
|
||||
return ErrorClose();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : Socket_TCP::SendData
|
||||
// Description : Ok Lets Send the Data
|
||||
//
|
||||
// Return type : int
|
||||
// - if error
|
||||
// 0 if socket closed for write or lengh is 0
|
||||
// + bytes writen ( May be smaller than requested)
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline int Socket_TCP::SendData(const char * data, int size)
|
||||
{
|
||||
return DO_SOCKET_WRITE(_socket, data, size);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : Socket_TCP::RecvData
|
||||
// Description : Read the data from the connection
|
||||
//
|
||||
// Return type : int
|
||||
// - if error
|
||||
// 0 if socket closed for read or length is 0
|
||||
// + bytes read ( May be smaller than requested)
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline int Socket_TCP::RecvData(char * data, int len)
|
||||
{
|
||||
int ecode = DO_SOCKET_READ(_socket, data, len);
|
||||
return ecode;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : Socket_TCP::RecvData
|
||||
// Description : Read the data from the connection
|
||||
//
|
||||
// Return type : int
|
||||
// - if error
|
||||
// 0 if socket closed for read or length is 0
|
||||
// + bytes read ( May be smaller than requested)
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline std::string Socket_TCP::RecvData(int max_len)
|
||||
{
|
||||
std::string str;
|
||||
char *buffer = (char *) malloc(max_len+1);
|
||||
int ecode = RecvData(buffer,max_len);
|
||||
if(ecode > 0)
|
||||
str.assign(buffer,ecode);
|
||||
|
||||
free(buffer);
|
||||
return str;
|
||||
};
|
||||
|
||||
|
||||
inline bool Socket_TCP::ErrorIs_WouldBlocking(int err)
|
||||
{
|
||||
return (GETERROR() == LOCAL_BLOCKING_ERROR);
|
||||
}
|
||||
|
||||
inline bool Socket_TCP::ShutdownSend()
|
||||
{
|
||||
return do_shutdown_send(_socket);
|
||||
};
|
||||
|
||||
/*
|
||||
inline bool Socket_TCP::DoNotLinger()
|
||||
{
|
||||
int bOption = 1;
|
||||
if (setsockopt(_socket, SOL_SOCKET, SO_DONTLINGER, (const char *)&bOption, sizeof(bOption)) != 0)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
*/
|
||||
|
||||
inline int Socket_TCP::SendData(const std::string &str)
|
||||
{
|
||||
return SendData(str.data(), str.size());
|
||||
};
|
||||
|
||||
#endif //__SOCKET_TCP_H__
|
||||
|
|
|
|||
|
|
@ -1,62 +1,62 @@
|
|||
#ifndef __SOCKET_TCP_LISTEN_H__
|
||||
#define __SOCKET_TCP_LISTEN_H__
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
// Class : Socket_TCP_Listen
|
||||
// Description : Base functionality for a TCP rendezvous socket
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
class Socket_TCP_Listen : public Socket_IP
|
||||
{
|
||||
public:
|
||||
PUBLISHED:
|
||||
Socket_TCP_Listen() {};
|
||||
~Socket_TCP_Listen() {};
|
||||
inline bool OpenForListen(Socket_Address & Inaddess, int backlog_size = 1024);
|
||||
inline bool GetIncomingConnection(Socket_TCP & newsession, Socket_Address &address);
|
||||
public:
|
||||
inline bool GetIncomingConnection(SOCKET & newsession, Socket_Address &address);
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : OpenForListen
|
||||
// Description : This function will initialize a listening Socket
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline bool Socket_TCP_Listen::OpenForListen(Socket_Address & Inaddess, int backlog_size )
|
||||
{
|
||||
ErrorClose();
|
||||
_socket = DO_NEWTCP();
|
||||
|
||||
SetReuseAddress();
|
||||
|
||||
if (DO_BIND(_socket, &Inaddess.GetAddressInfo()) != 0)
|
||||
return ErrorClose();
|
||||
|
||||
if (DO_LISTEN(_socket, backlog_size) != 0)
|
||||
return ErrorClose();
|
||||
|
||||
return true;
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : GetIncomingConnection
|
||||
// Description : This function is used to accept new connections
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline bool Socket_TCP_Listen::GetIncomingConnection(SOCKET & newsession, Socket_Address &address)
|
||||
{
|
||||
newsession = DO_ACCEPT(_socket, &address.GetAddressInfo());
|
||||
if (newsession == BAD_SOCKET)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
inline bool Socket_TCP_Listen::GetIncomingConnection(Socket_TCP & newsession, Socket_Address &address)
|
||||
{
|
||||
SOCKET sck;
|
||||
if(!GetIncomingConnection(sck,address))
|
||||
return false;
|
||||
|
||||
newsession.SetSocket(sck);
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif //__SOCKET_TCP_LISTEN_H__
|
||||
#ifndef __SOCKET_TCP_LISTEN_H__
|
||||
#define __SOCKET_TCP_LISTEN_H__
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
// Class : Socket_TCP_Listen
|
||||
// Description : Base functionality for a TCP rendezvous socket
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA Socket_TCP_Listen : public Socket_IP
|
||||
{
|
||||
public:
|
||||
PUBLISHED:
|
||||
Socket_TCP_Listen() {};
|
||||
~Socket_TCP_Listen() {};
|
||||
inline bool OpenForListen(Socket_Address & Inaddess, int backlog_size = 1024);
|
||||
inline bool GetIncomingConnection(Socket_TCP & newsession, Socket_Address &address);
|
||||
public:
|
||||
inline bool GetIncomingConnection(SOCKET & newsession, Socket_Address &address);
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : OpenForListen
|
||||
// Description : This function will initialize a listening Socket
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline bool Socket_TCP_Listen::OpenForListen(Socket_Address & Inaddess, int backlog_size )
|
||||
{
|
||||
ErrorClose();
|
||||
_socket = DO_NEWTCP();
|
||||
|
||||
SetReuseAddress();
|
||||
|
||||
if (DO_BIND(_socket, &Inaddess.GetAddressInfo()) != 0)
|
||||
return ErrorClose();
|
||||
|
||||
if (DO_LISTEN(_socket, backlog_size) != 0)
|
||||
return ErrorClose();
|
||||
|
||||
return true;
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : GetIncomingConnection
|
||||
// Description : This function is used to accept new connections
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline bool Socket_TCP_Listen::GetIncomingConnection(SOCKET & newsession, Socket_Address &address)
|
||||
{
|
||||
newsession = DO_ACCEPT(_socket, &address.GetAddressInfo());
|
||||
if (newsession == BAD_SOCKET)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
inline bool Socket_TCP_Listen::GetIncomingConnection(Socket_TCP & newsession, Socket_Address &address)
|
||||
{
|
||||
SOCKET sck;
|
||||
if(!GetIncomingConnection(sck,address))
|
||||
return false;
|
||||
|
||||
newsession.SetSocket(sck);
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif //__SOCKET_TCP_LISTEN_H__
|
||||
|
|
|
|||
|
|
@ -1,96 +1,96 @@
|
|||
#ifndef __SOCKET_UDP_OUTGOING_H__
|
||||
#define __SOCKET_UDP_OUTGOING_H__
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
// Class : Socket_UDP_Outgoing
|
||||
//
|
||||
// Description : Base functionality for a UDP Sending Socket
|
||||
//
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
class Socket_UDP_Outgoing : public Socket_IP
|
||||
{
|
||||
public:
|
||||
PUBLISHED:
|
||||
// use this interface for a tagreted UDP connection
|
||||
inline bool InitToAddress(Socket_Address & address);
|
||||
inline bool Send(const char * data, int len);
|
||||
// use this interface for a none tagreted UDP connection
|
||||
inline bool InitNoAddress();
|
||||
inline bool SendTo(const char * data, int len, const Socket_Address & address);
|
||||
inline bool SetToBroadCast();
|
||||
};
|
||||
//////////////////////////////////////////////////////////////
|
||||
// Function name : Socket_UDP_Outgoing:SetToBroadCast
|
||||
// Description : Ask the OS to let us receive BROADCASt packets on this port..
|
||||
// Return type : bool
|
||||
// Argument : void
|
||||
//////////////////////////////////////////////////////////////
|
||||
inline bool Socket_UDP_Outgoing::SetToBroadCast()
|
||||
{
|
||||
int optval = 1;
|
||||
|
||||
if (setsockopt(_socket, SOL_SOCKET, SO_BROADCAST, (char *)&optval, sizeof(optval)) != 0)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : Socket_UDP_Outgoing::InitToAddress
|
||||
// Description : Connects the Socket to a Specified address
|
||||
//
|
||||
// Return type : inline bool
|
||||
// Argument : NetAddress & address
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline bool Socket_UDP_Outgoing::InitToAddress(Socket_Address & address)
|
||||
{
|
||||
if (InitNoAddress() != true)
|
||||
return false;
|
||||
|
||||
if (DO_CONNECT(_socket, &address.GetAddressInfo()) != 0)
|
||||
return ErrorClose();
|
||||
|
||||
return true;
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : Socket_UDP_Outgoing::InitNoAddress
|
||||
// Description : This will set a udp up for targeted sends..
|
||||
//
|
||||
// Return type : inline bool
|
||||
// Argument : void
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline bool Socket_UDP_Outgoing::InitNoAddress()
|
||||
{
|
||||
Close();
|
||||
_socket = DO_NEWUDP();
|
||||
if (_socket == BAD_SOCKET)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : Socket_UDP_Outgoing::Send
|
||||
// Description : Send data to connected address
|
||||
//
|
||||
// Return type : inline bool
|
||||
// Argument : char * data
|
||||
// Argument : int len
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline bool Socket_UDP_Outgoing::Send(const char * data, int len)
|
||||
{
|
||||
return (DO_SOCKET_WRITE(_socket, data, len) == len);
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : Socket_UDP_Outgoing::SendTo
|
||||
// Description : Send data to specified address
|
||||
//
|
||||
// Return type : inline bool
|
||||
// Argument : char * data
|
||||
// Argument : int len
|
||||
// Argument : NetAddress & address
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline bool Socket_UDP_Outgoing::SendTo(const char * data, int len, const Socket_Address & address)
|
||||
{
|
||||
return (DO_SOCKET_WRITE_TO(_socket, data, len, &address.GetAddressInfo()) == len);
|
||||
}
|
||||
|
||||
#endif //__SOCKET_UDP_OUTGOING_H__
|
||||
#ifndef __SOCKET_UDP_OUTGOING_H__
|
||||
#define __SOCKET_UDP_OUTGOING_H__
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
// Class : Socket_UDP_Outgoing
|
||||
//
|
||||
// Description : Base functionality for a UDP Sending Socket
|
||||
//
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA Socket_UDP_Outgoing : public Socket_IP
|
||||
{
|
||||
public:
|
||||
PUBLISHED:
|
||||
// use this interface for a tagreted UDP connection
|
||||
inline bool InitToAddress(Socket_Address & address);
|
||||
inline bool Send(const char * data, int len);
|
||||
// use this interface for a none tagreted UDP connection
|
||||
inline bool InitNoAddress();
|
||||
inline bool SendTo(const char * data, int len, const Socket_Address & address);
|
||||
inline bool SetToBroadCast();
|
||||
};
|
||||
//////////////////////////////////////////////////////////////
|
||||
// Function name : Socket_UDP_Outgoing:SetToBroadCast
|
||||
// Description : Ask the OS to let us receive BROADCASt packets on this port..
|
||||
// Return type : bool
|
||||
// Argument : void
|
||||
//////////////////////////////////////////////////////////////
|
||||
inline bool Socket_UDP_Outgoing::SetToBroadCast()
|
||||
{
|
||||
int optval = 1;
|
||||
|
||||
if (setsockopt(_socket, SOL_SOCKET, SO_BROADCAST, (char *)&optval, sizeof(optval)) != 0)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : Socket_UDP_Outgoing::InitToAddress
|
||||
// Description : Connects the Socket to a Specified address
|
||||
//
|
||||
// Return type : inline bool
|
||||
// Argument : NetAddress & address
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline bool Socket_UDP_Outgoing::InitToAddress(Socket_Address & address)
|
||||
{
|
||||
if (InitNoAddress() != true)
|
||||
return false;
|
||||
|
||||
if (DO_CONNECT(_socket, &address.GetAddressInfo()) != 0)
|
||||
return ErrorClose();
|
||||
|
||||
return true;
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : Socket_UDP_Outgoing::InitNoAddress
|
||||
// Description : This will set a udp up for targeted sends..
|
||||
//
|
||||
// Return type : inline bool
|
||||
// Argument : void
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline bool Socket_UDP_Outgoing::InitNoAddress()
|
||||
{
|
||||
Close();
|
||||
_socket = DO_NEWUDP();
|
||||
if (_socket == BAD_SOCKET)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : Socket_UDP_Outgoing::Send
|
||||
// Description : Send data to connected address
|
||||
//
|
||||
// Return type : inline bool
|
||||
// Argument : char * data
|
||||
// Argument : int len
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline bool Socket_UDP_Outgoing::Send(const char * data, int len)
|
||||
{
|
||||
return (DO_SOCKET_WRITE(_socket, data, len) == len);
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : Socket_UDP_Outgoing::SendTo
|
||||
// Description : Send data to specified address
|
||||
//
|
||||
// Return type : inline bool
|
||||
// Argument : char * data
|
||||
// Argument : int len
|
||||
// Argument : NetAddress & address
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline bool Socket_UDP_Outgoing::SendTo(const char * data, int len, const Socket_Address & address)
|
||||
{
|
||||
return (DO_SOCKET_WRITE_TO(_socket, data, len, &address.GetAddressInfo()) == len);
|
||||
}
|
||||
|
||||
#endif //__SOCKET_UDP_OUTGOING_H__
|
||||
|
|
|
|||
Loading…
Reference in New Issue