nSocket Class Reference

wrapper for low level sockets. More...

#include <nSocket.h>

Collaboration diagram for nSocket:

Collaboration graph
[legend]

List of all members.

Public Member Functions

 nSocket ()
 constructor
 ~nSocket ()
 destructor
int Open ()
 open socket for sending data ( not bound to a specific IP or port )
int Open (nAddress const &address)
 open socket for listening on the specified address info
int Open (int port)
 open socket for listening bound to the specified port
int Open (const nHostInfo &addr)
 open socket for listening on the specified host info
int Close ()
 close the socket
bool IsOpen () const
 returns whether the socket is open
void Reset () const
 resets ( closes and reopens ) the socket
int Connect (const nAddress &addr)
 connects the socket to the specified address
const nSocketCheckNewConnection () const
 listens for new data
int Read (int8 *buf, int len, nAddress &addr) const
 reads data from the socket
int Write (const int8 *buf, int len, const nAddress &addr) const
 writes data to the socket
int Broadcast (const char *buf, int len, unsigned int port) const
 broadcasts data over the socket to the LAN
nAddress const & GetAddress (void) const
 Gets the address the socket is bound to.
nSocket const & GetAddress (nAddress &address) const
 Gets the address the socket is bound to.
int GetSocket (void) const
 Gets the raw socket.
nSocket const & GetSocket (int &socket) const
 Gets the raw socket.
void MoveFrom (const nSocket &other)
 move data from other to this
 nSocket (const nSocket &other)
 copy constructor. Warning: uses data move semantics
nSocketoperator= (const nSocket &other)
 copy operator. Warning: uses data move semantics

Private Member Functions

int Create ()
 creates the socket without binding it
int Bind (nAddress const &address)
 binds the socket to a specific address
int Write (const int8 *buf, int len, const sockaddr *addr, int addrlen) const
 writes data to the socket
nSocketSetAddress (nAddress const &address)
 Sets the address the socket is bound to.
nSocketSetSocket (int socket)
 Sets the raw socket.

Private Attributes

int socket_
 the raw socket
nAddress address_
 the address the socket is bound to
nAddress trueAddress_
 the address the socket is really bound to
int family_
int socktype_
int protocol_
 more low level data determining the socket type
bool broadcast_
 flag indicating whether this socket has been prepared for broadcasts

Classes

class  PermanentError
 exception thrown on probably unrecoverable error More...


Detailed Description

wrapper for low level sockets.

Definition at line 121 of file nSocket.h.


Constructor & Destructor Documentation

nSocket::nSocket ( void   ) 

constructor

Definition at line 1486 of file nSocket.cpp.

01489         :socket_( -1 ), family_( PF_INET ), socktype_( SOCK_DGRAM ), protocol_( IPPROTO_UDP ), broadcast_( false )

nSocket::~nSocket ( void   ) 

destructor

Definition at line 1500 of file nSocket.cpp.

References Close(), and IsOpen().

01503 {
01504     if ( IsOpen() )

Here is the call graph for this function:

nSocket::nSocket ( const nSocket other  ) 

copy constructor. Warning: uses data move semantics

Parameters:
other socket to move data from

Definition at line 2292 of file nSocket.cpp.

References MoveFrom(), and socket_.

02295 {
02296     socket_ = -1;

Here is the call graph for this function:


Member Function Documentation

int nSocket::Open ( void   ) 

open socket for sending data ( not bound to a specific IP or port )

Returns:
0 on success

Definition at line 1698 of file nSocket.cpp.

Referenced by ANET_ListenOn(), nBasicNetworkSystem::Init(), Open(), and Reset().

01701 {
01702     // bind to unspecific IP
01703     nAddress addr;

Here is the caller graph for this function:

int nSocket::Open ( nAddress const &  addr  ) 

open socket for listening on the specified address info

Parameters:
addr address to bind to
Returns:
0 on success

Definition at line 1674 of file nSocket.cpp.

References Bind(), Create(), IsOpen(), and tASSERT.

01677 {
01678     tASSERT( !IsOpen() );
01679 
01680     // create
01681     if ( Create() != 0 )
01682     {
01683         return -2;
01684     }
01685 
01686     // bind

Here is the call graph for this function:

int nSocket::Open ( int  port  ) 

open socket for listening bound to the specified port

Parameters:
port port to bind to
Returns:
0 on success

Definition at line 1716 of file nSocket.cpp.

References Open(), and nAddress::SetPort().

01719 {
01720     // bind to unspecific IP, but specific port
01721     nAddress addr;
01722     addr.SetPort( port );

Here is the call graph for this function:

int nSocket::Open ( const nHostInfo addr  ) 

open socket for listening on the specified host info

Parameters:
addr address to bind to
Returns:
0 on success
Parameters:
addr host info to take opening information from
Returns:
0 on success

Definition at line 1766 of file nSocket.cpp.

References nHostInfo::address, nSocketType::family, family_, IsOpen(), Open(), nSocketType::protocol, protocol_, socktype_, tASSERT, nSocketType::type, and nHostInfo::type.

01769 {
01770     tASSERT( !IsOpen() );
01771 
01772     family_ = addr.type.family;
01773     socktype_ = addr.type.type;
01774     protocol_ = addr.type.protocol;
01775 

Here is the call graph for this function:

int nSocket::Close ( void   ) 

close the socket

Returns:
0 on success

Definition at line 1787 of file nSocket.cpp.

References ANET_CloseSocket(), broadcast_, con, socket_, nAddress::ToString(), and trueAddress_.

Referenced by MoveFrom(), Reset(), nBasicNetworkSystem::Shutdown(), and ~nSocket().

01790 {
01791 #ifdef DEDICATED
01792     if ( socket_ != -1 )
01793         con << "Closing socket bound to " << trueAddress_.ToString() << "\n";
01794 #endif
01795 
01796     ANET_CloseSocket( socket_ );
01797     socket_ = -1;
01798     broadcast_ = false;
01799 

Here is the call graph for this function:

Here is the caller graph for this function:

bool nSocket::IsOpen ( void   )  const

returns whether the socket is open

Returns:
true if the socket is open, false otherwise

Definition at line 1849 of file nSocket.cpp.

References socket_.

Referenced by Bind(), Broadcast(), CheckNewConnection(), Create(), nBasicNetworkSystem::Init(), MoveFrom(), Open(), Read(), Write(), and ~nSocket().

01852 {

Here is the caller graph for this function:

void nSocket::Reset ( void   )  const

resets ( closes and reopens ) the socket

Returns:

Definition at line 1811 of file nSocket.cpp.

References address_, Close(), nAddress::GetPort(), Open(), nAddress::SetPort(), and trueAddress_.

Referenced by CheckNewConnection(), Read(), and Write().

01814 {
01815     // logically, resetting is const. Physically not. const_cast is required.
01816     nSocket * reset = const_cast< nSocket * >( this );
01817 
01818     // remember the true address bound to
01819     nAddress trueAddress = trueAddress_;
01820 
01821     // try to reset a socket without disturbing the rest of the system
01822     reset->Close();
01823 
01824     // store old address
01825     nAddress oldAddress = address_;
01826 
01827     // first try: reopen with the same port as last time
01828     nAddress wishAddress = address_;
01829     wishAddress.SetPort( trueAddress.GetPort() );
01830     if ( 0 == reset->Open( wishAddress ) )
01831         return;
01832 
01833     // second try: reopen with the same premises
01834     if ( 0 == reset->Open( oldAddress ) )
01835         return;
01836 
01837     // last try: reopen with the last true address ( this is most probably wrong )

Here is the call graph for this function:

Here is the caller graph for this function:

int nSocket::Connect ( const nAddress addr  ) 

connects the socket to the specified address

Parameters:
addr 
Returns:

Definition at line 1865 of file nSocket.cpp.

01868 {
01869     // not implemented, does not make sense here

const nSocket * nSocket::CheckNewConnection ( void   )  const

listens for new data

Returns:
the new socket if a connection is there or NULL

Definition at line 1895 of file nSocket.cpp.

References ANET_Error(), IsOpen(), tRecorderBase::IsRunning(), nSocketError_Ignore, nSocketError_Reset, NULL, Reset(), socket_, Sys_Error(), and tASSERT.

01898 {
01899     tASSERT( IsOpen() );
01900 
01901     int available=-1;
01902 
01903     // see if the playback has anything to say
01904     //if ( tRecorder::Playback( recordingSectionConnect, available ) )
01905     //    return this;
01906 
01907     // always return this when recoring or playback are running
01908     if ( tRecorder::IsRunning() )
01909         return this;
01910 
01911 
01912 #ifdef DEBUG
01913     if ( sn_ResetSocket )
01914     {
01915         sn_ResetSocket = false;
01916         Reset();
01917     }
01918 #endif
01919 
01920     //    for ( SocketArray::iterator iter = sockets.begin(); iter != sockets.end(); ++iter )
01921     int ret = ioctl (socket_, FIONREAD, &available);
01922     if ( ret == -1)
01923     {
01924         switch ( ANET_Error() )
01925         {
01926         case nSocketError_Reset:
01927             Reset();
01928             break;
01929         case nSocketError_Ignore:
01930             break;
01931         default:
01932             Sys_Error ("UDP: ioctlsocket (FIONREAD) failed\n");
01933             break;
01934         }
01935     }
01936 
01937     if ( ret >= 0 )
01938     {
01939         // record result
01940         // tRecorder::Record( recordingSectionConnect, available );
01941         return this;
01942     }
01943 

Here is the call graph for this function:

int nSocket::Read ( int8 buf,
int  len,
nAddress addr 
) const

reads data from the socket

Parameters:
buf buffer to read to
len maximum number of bytes to read
addr the address where the data came from is stored here
Returns:
number of bytes truly read or something negative on failure

Definition at line 1998 of file nSocket.cpp.

References ANET_Error(), ReadArchiver< Archiver >::Archive(), con, tRandomizer::Get(), nAddress::GetAddressLength(), IsOpen(), nSocketError_Ignore, nSocketError_Reset, Reset(), socket_, tASSERT, nAddress::ToString(), and trueAddress_.

Referenced by rec_peer(), and sn_DiscardFromControlSocket().

02001 {
02002     tASSERT( IsOpen() );
02003 
02004     // return value: real number of bytes read
02005     int ret = 0;
02006 
02007     static tReproducibleRandomizer randomizer;
02008 #ifdef DEBUG
02009     // pretend nothing was received
02010     if ( sn_simulateReceivePacketLoss > randomizer.Get() )
02011         return -1;
02012 #endif
02013 
02014     // check playback
02015     if ( !ReadArchiver< tPlaybackBlock >::Archive( buf, ret, addr ) )
02016     {
02017 
02018 #ifdef DEBUG
02019         if ( sn_ResetSocket )
02020         {
02021             sn_ResetSocket = false;
02022             Reset();
02023         }
02024 #endif
02025 
02026         // really receive
02027         NET_SIZE addrlen = addr.GetAddressLength();
02028         ret = recvfrom (socket_, buf, len, 0, addr, &addrlen );
02029         tASSERT( addrlen <= static_cast< NET_SIZE >( addr.GetAddressLength() ) );
02030     }
02031 
02032     // write recording
02033     ReadArchiver< tRecordingBlock >::Archive( buf, ret, addr );
02034 
02035     if ( ret <= 0 )
02036     {
02037         switch ( ANET_Error() )
02038         {
02039         case nSocketError_Reset:
02040             {
02041                 Reset();
02042                 return -1;
02043             }
02044             break;
02045         case nSocketError_Ignore:
02046             return -1;
02047             break;
02048         }
02049     }
02050 
02051     if ( ret >= 0 )
02052     {
02053         // con << "Read " << ret << " bytes from socket " << GetSocket() << ".\n";
02054     }
02055 
02056 #ifdef PRINTPACKETS
02057     con << trueAddress_.ToString() << " << " << addr.ToString() << "\n";
02058 #endif
02059 

Here is the call graph for this function:

Here is the caller graph for this function:

int nSocket::Write ( const int8 buf,
int  len,
const nAddress addr 
) const

writes data to the socket

Parameters:
buf pointer to data to send
len length of data to send
addr address to send data to
Returns:
the number of bytes sent or something negative on error

Definition at line 2148 of file nSocket.cpp.

References con, nAddress::GetAddressLength(), nAddress::ToString(), and trueAddress_.

Referenced by Broadcast(), and nSendBuffer::Send().

02151 {
02152 #ifdef PRINTPACKETS
02153     con << trueAddress_.ToString() << " >> " << addr.ToString() << "\n";
02154 #endif
02155 
02156     // delegate to low level write

Here is the call graph for this function:

Here is the caller graph for this function:

int nSocket::Broadcast ( const char *  buf,
int  len,
unsigned int  port 
) const

broadcasts data over the socket to the LAN

Parameters:
buf pointer to data to send
len length of data to send
port port to broadcast on
Returns:
number of bytes truly send or something negative on error

Definition at line 2171 of file nSocket.cpp.

References broadcast_, Con_Printf(), IsOpen(), socket_, tASSERT, and Write().

Referenced by nSendBuffer::Broadcast().

02174 {
02175     tASSERT( IsOpen() );
02176 
02177     if ( !broadcast_ )
02178     {
02179         int                             i = 1;
02180 
02181         // make this socket broadcast capable
02182         if (setsockopt(socket_, SOL_SOCKET, SO_BROADCAST, (char *)&i, sizeof(i)) < 0)
02183         {
02184             Con_Printf("Unable to make socket broadcast capable\n");
02185             return -1;
02186         }
02187 
02188         broadcast_ = true;
02189     }
02190 
02191     // prepare broadcasting address
02192     sockaddr_in broadcastaddr;
02193     broadcastaddr.sin_family = AF_INET;
02194     broadcastaddr.sin_addr.s_addr = INADDR_BROADCAST;
02195     broadcastaddr.sin_port = htons(port);
02196 
02197     // delegate to usual write function

Here is the call graph for this function:

Here is the caller graph for this function:

const nAddress & nSocket::GetAddress ( void   )  const

Gets the address the socket is bound to.

Returns:
the address the socket is bound to

Definition at line 2209 of file nSocket.cpp.

References trueAddress_.

Referenced by nServerInfoBase::DoGetFrom(), and nServerInfo::GetBigServerInfoCommon().

02212 {

Here is the caller graph for this function:

const nSocket & nSocket::GetAddress ( nAddress address  )  const

Gets the address the socket is bound to.

Parameters:
address the address that the socket is bound to to fill
Returns:
reference to this for chaining

Definition at line 2225 of file nSocket.cpp.

References trueAddress_.

02228 {
02229     address = trueAddress_;
02230 

int nSocket::GetSocket ( void   )  const [inline]

Gets the raw socket.

Returns:
the raw socket

Definition at line 311 of file nSocket.h.

References socket_.

Referenced by nBasicNetworkSystem::Select().

00312 {
00313     return this->socket_;
00314 }

Here is the caller graph for this function:

nSocket const & nSocket::GetSocket ( int &  socket  )  const [inline]

Gets the raw socket.

Parameters:
socket the raw socket to fill
Returns:
A reference to this to allow chaining

Definition at line 327 of file nSocket.h.

References socket_.

00328 {
00329     socket = this->socket_;
00330     return *this;
00331 }

void nSocket::MoveFrom ( const nSocket other  ) 

move data from other to this

Parameters:
other socket to move data from

Definition at line 2262 of file nSocket.cpp.

References address_, broadcast_, Close(), family_, IsOpen(), protocol_, socket_, socktype_, and trueAddress_.

Referenced by nSocket(), and operator=().

02265 {
02266     // close this socket
02267     if ( IsOpen() )
02268         Close();
02269 
02270 
02271     // copy uncritical data
02272     address_ = other.address_;
02273     trueAddress_ = other.trueAddress_;
02274     family_ = other.family_;
02275     socktype_ = other.socktype_;
02276     protocol_ = other.protocol_;
02277     broadcast_ = other.broadcast_;
02278 
02279     // move socket
02280     socket_ = other.socket_;

Here is the call graph for this function:

Here is the caller graph for this function:

nSocket & nSocket::operator= ( const nSocket other  ) 

copy operator. Warning: uses data move semantics

Parameters:
other socket to move data from
Returns:
reference to this

Definition at line 2309 of file nSocket.cpp.

References MoveFrom().

02312 {
02313     MoveFrom( other );

Here is the call graph for this function:

int nSocket::Create ( void   )  [private]

creates the socket without binding it

Returns:
0 on success

Definition at line 1516 of file nSocket.cpp.

References _true, con, family_, IsOpen(), protocol_, sn_InitOSNetworking(), socket_, socktype_, and tASSERT.

Referenced by Open().

01519 {
01520     tASSERT( !IsOpen() );
01521 
01522     // initialize networking at OS level
01523     sn_InitOSNetworking();
01524 
01525     // open new socket
01526     socket_ = socket( family_, socktype_, protocol_ );
01527     if ( socket_ < 0 )
01528         return -1;
01529 
01530     // TODO: IP_TOS only Supported under Windows 2000
01531     // See: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winsock/winsock/socket_options.asp
01532 
01533     // Tutorial on using Windows 98+ RSVP (QoS / Resource reSerVation Protocol)
01534     // http://msdn.microsoft.com/msdnmag/issues/01/04/qos/default.aspx
01535 
01536     // set TOS to low latency ( see manpages getsockopt(2), ip(7) and socket(7) )
01537     // maybe this works for Windows, too?
01538 #ifndef WIN32
01539     char tos = IPTOS_LOWDELAY;
01540 
01541     int ret = setsockopt( socket_, IPPROTO_IP, IP_TOS, &tos, sizeof(char) );
01542 
01543     // remove this error reporting some time later, the success is not critical
01544     if ( ret != 0 )
01545     {
01546         static bool warn=true;
01547         if ( warn )
01548             con << "Setting TOS to LOWDELAY failed.\n";
01549         warn=false;
01550     }
01551 #endif    
01552 
01553     // unblock it
01554     bool _true = true;

Here is the call graph for this function:

Here is the caller graph for this function:

int nSocket::Bind ( nAddress const &  addr  )  [private]

binds the socket to a specific address

Parameters:
addr address to bind to
Returns:
0 on success

Definition at line 1601 of file nSocket.cpp.

References address_, ANET_CloseSocket(), ANET_Error(), ANET_GetSocketAddr(), BindArchiver< Archiver >::Archive(), nAddress::Compare(), con, nAddress::GetAddressLength(), IsOpen(), nSocketError_Reset, socket_, tASSERT, nAddress::ToString(), and trueAddress_.

Referenced by Open().

01604 {
01605     tASSERT( IsOpen() );
01606 
01607     // copy address
01608     address_ = addr;
01609 
01610     int ret = 0;
01611 
01612     // see if the process was archived; if yes, return without action
01613     if ( !BindArchiver< tPlaybackBlock >::Archive( ret, trueAddress_ ) )
01614     {
01615         // just delegate
01616         ret = bind( socket_, addr, addr.GetAddressLength() );
01617 
01618         // read true address
01619         if ( 0 == ret )
01620             ANET_GetSocketAddr( socket_, trueAddress_ );
01621     }
01622 
01623     // record the bind
01624     BindArchiver< tRecordingBlock >::Archive( ret, trueAddress_ );
01625 
01626     if ( 0 == ret )
01627     {
01628         // report success
01629 #ifdef DEDICATED
01630         static nAddress nullAddress;
01631         if ( 0 == nAddress::Compare( trueAddress_, addr ) || 0 == nAddress::Compare( nullAddress, addr ) )
01632             con << "Bound socket to " << trueAddress_.ToString() << ".\n";
01633         else
01634             con << "Bound socket to " << trueAddress_.ToString() << " ( " << address_.ToString() << " was requested ).\n";
01635 #endif
01636 
01637         return 0;
01638     }
01639     else
01640     {
01641         // con << "nSocket::Open: Failed to bind socket to " << addr.ToString() << ".\n";
01642 
01643         // close the socket and report an error
01644         ANET_CloseSocket( socket_ );
01645         socket_ = -1;
01646 
01647         // throw exception on fatal error
01648 #ifndef NOEXCEPT
01649         // name lookup failures won't be tolerated here
01650         if ( ANET_Error() == nSocketError_Reset )
01651         {
01652             tString details( "Unable to bind to " );
01653             details += address_.ToString();
01654             details += " because that is not an address of the local machine.";
01655             throw nSocket::PermanentError( details );
01656         }
01657 #endif
01658 
01659         return -1;
01660     }
01661 

Here is the call graph for this function:

Here is the caller graph for this function:

int nSocket::Write ( const int8 buf,
int  len,
const sockaddr *  addr,
int  addrlen 
) const [private]

writes data to the socket

Parameters:
buf pointer to data to send
len length of data to send
addr address to send data to
addrlen length of address data structure
Returns:
the number of bytes sent or something negative on error

Definition at line 2080 of file nSocket.cpp.

References ANET_Error(), tRandomizer::Get(), IsOpen(), tRecorderBase::IsPlayingBack(), nSocketError_Ignore, nSocketError_Reset, tRecorder::Playback(), tRecorder::Record(), Reset(), section, socket_, and tASSERT.

02083 {
02084     tASSERT( IsOpen() );
02085 
02086 #ifdef DEBUG
02087     if ( sn_ResetSocket )
02088     {
02089         sn_ResetSocket = false;
02090         Reset();
02091     }
02092 #endif
02093 
02094     int ret = 0;
02095 
02096     // check if return value was archived
02097     static char const * section = "SEND";
02098     if ( !tRecorder::Playback( section, ret ) )
02099     {
02100         static tReproducibleRandomizer randomizer;
02101 #ifdef DEBUG
02102         // pretend send was successful in packet loss simulation
02103         if ( sn_simulateSendPacketLoss > randomizer.Get() )
02104             ret = len;
02105         else
02106 #endif
02107         {
02108             // don't send if a playback is running
02109             if ( !tRecorder::IsPlayingBack() )
02110                 ret = sendto (socket_, buf, len, 0, addr, addrlen );
02111         }
02112     }
02113 
02114     if ( ret < 0 )
02115     {
02116         // log error
02117         tRecorder::Record( section, ret );
02118 
02119         // handle error
02120         switch ( ANET_Error() )
02121         {
02122         case nSocketError_Reset:
02123             {
02124                 Reset();
02125                 return -1;
02126             }
02127             break;
02128         case nSocketError_Ignore:
02129             return -1;
02130             break;
02131         }
02132     }
02133 

Here is the call graph for this function:

nSocket & nSocket::SetAddress ( nAddress const &  address  )  [private]

Sets the address the socket is bound to.

Parameters:
address address the address that the socket should be bound to
Returns:

Definition at line 2243 of file nSocket.cpp.

References address_, and trueAddress_.

02246 {
02247     address_ = address;
02248     trueAddress_ = address;
02249 

nSocket & nSocket::SetSocket ( int  socket  )  [inline, private]

Sets the raw socket.

Parameters:
socket the raw socket to set
Returns:
A reference to this to allow chaining

Definition at line 344 of file nSocket.h.

References socket_.

00345 {
00346     this->socket_ = socket;
00347     return *this;
00348 }


Member Data Documentation

int nSocket::socket_ [private]

the raw socket

Definition at line 176 of file nSocket.h.

Referenced by Bind(), Broadcast(), CheckNewConnection(), Close(), Create(), GetSocket(), IsOpen(), MoveFrom(), nSocket(), Read(), SetSocket(), and Write().

nAddress nSocket::address_ [private]

the address the socket is bound to

Definition at line 177 of file nSocket.h.

Referenced by Bind(), MoveFrom(), Reset(), and SetAddress().

nAddress nSocket::trueAddress_ [private]

the address the socket is really bound to

Definition at line 178 of file nSocket.h.

Referenced by Bind(), Close(), GetAddress(), MoveFrom(), Read(), Reset(), SetAddress(), and Write().

int nSocket::family_ [private]

Definition at line 179 of file nSocket.h.

Referenced by Create(), MoveFrom(), and Open().

int nSocket::socktype_ [private]

Definition at line 179 of file nSocket.h.

Referenced by Create(), MoveFrom(), and Open().

int nSocket::protocol_ [private]

more low level data determining the socket type

Definition at line 179 of file nSocket.h.

Referenced by Create(), MoveFrom(), and Open().

bool nSocket::broadcast_ [mutable, private]

flag indicating whether this socket has been prepared for broadcasts

Definition at line 180 of file nSocket.h.

Referenced by Broadcast(), Close(), and MoveFrom().


The documentation for this class was generated from the following files:
Generated on Sat Mar 15 23:50:51 2008 for Armagetron Advanced by  doxygen 1.5.4