#include <nSocket.h>
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 nSocket * | CheckNewConnection () 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 | |
nSocket & | operator= (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 | |
nSocket & | SetAddress (nAddress const &address) |
Sets the address the socket is bound to. | |
nSocket & | SetSocket (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... |
Definition at line 121 of file nSocket.h.
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() )
nSocket::nSocket | ( | const nSocket & | other | ) |
copy constructor. Warning: uses data move semantics
other | socket to move data from |
Definition at line 2292 of file nSocket.cpp.
References MoveFrom(), and socket_.
02295 { 02296 socket_ = -1;
int nSocket::Open | ( | void | ) |
open socket for sending data ( not bound to a specific IP or port )
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;
int nSocket::Open | ( | nAddress const & | addr | ) |
open socket for listening on the specified address info
addr | address to bind to |
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
int nSocket::Open | ( | int | port | ) |
open socket for listening bound to the specified port
port | port to bind to |
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 );
int nSocket::Open | ( | const nHostInfo & | addr | ) |
open socket for listening on the specified host info
addr | address to bind to |
addr | host info to take opening information from |
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
int nSocket::Close | ( | void | ) |
close the socket
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
bool nSocket::IsOpen | ( | void | ) | const |
returns whether the socket is open
Definition at line 1849 of file nSocket.cpp.
References socket_.
Referenced by Bind(), Broadcast(), CheckNewConnection(), Create(), nBasicNetworkSystem::Init(), MoveFrom(), Open(), Read(), Write(), and ~nSocket().
void nSocket::Reset | ( | void | ) | const |
resets ( closes and reopens ) the socket
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 )
int nSocket::Connect | ( | const nAddress & | addr | ) |
connects the socket to the specified address
addr |
Definition at line 1865 of file nSocket.cpp.
const nSocket * nSocket::CheckNewConnection | ( | void | ) | const |
listens for new data
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
reads data from the socket
buf | buffer to read to | |
len | maximum number of bytes to read | |
addr | the address where the data came from is stored here |
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
writes data to the socket
buf | pointer to data to send | |
len | length of data to send | |
addr | address to send data to |
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
int nSocket::Broadcast | ( | const char * | buf, | |
int | len, | |||
unsigned int | port | |||
) | const |
broadcasts data over the socket to the LAN
buf | pointer to data to send | |
len | length of data to send | |
port | port to broadcast on |
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
const nAddress & nSocket::GetAddress | ( | void | ) | const |
Gets the address the socket is bound to.
Definition at line 2209 of file nSocket.cpp.
References trueAddress_.
Referenced by nServerInfoBase::DoGetFrom(), and nServerInfo::GetBigServerInfoCommon().
Gets the address the socket is bound to.
address | the address that the socket is bound to to fill |
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.
Definition at line 311 of file nSocket.h.
References socket_.
Referenced by nBasicNetworkSystem::Select().
00312 { 00313 return this->socket_; 00314 }
nSocket const & nSocket::GetSocket | ( | int & | socket | ) | const [inline] |
void nSocket::MoveFrom | ( | const nSocket & | other | ) |
move data from other to this
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_;
copy operator. Warning: uses data move semantics
other | socket to move data from |
Definition at line 2309 of file nSocket.cpp.
References MoveFrom().
02312 { 02313 MoveFrom( other );
int nSocket::Create | ( | void | ) | [private] |
creates the socket without binding it
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;
int nSocket::Bind | ( | nAddress const & | addr | ) | [private] |
binds the socket to a specific address
addr | address to bind to |
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
int nSocket::Write | ( | const int8 * | buf, | |
int | len, | |||
const sockaddr * | addr, | |||
int | addrlen | |||
) | const [private] |
writes data to the socket
buf | pointer to data to send | |
len | length of data to send | |
addr | address to send data to | |
addrlen | length of address data structure |
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
Sets the address the socket is bound to.
address | address the address that the socket should be bound to |
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] |
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] |
int nSocket::socktype_ [private] |
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().