1 /*
2
3 *************************************************************************
4
5 ArmageTron -- Just another Tron Lightcycle Game in 3D.
6 Copyright (C) 2000 Manuel Moos (manuel@moosnet.de)
7
8 **************************************************************************
9
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License
12 as published by the Free Software Foundation; either version 2
13 of the License, or (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23
24 ***************************************************************************
25
26 */
27
28 // nSocket.h
29
30 // extremely losely based on the GNU Quake 1 base network code, so technicaly:
31 // Copyright (C) 1996-1997 Id Software, Inc.
32 // Modified for Armagetron by Manuel Moos (manuel@moosnet.de)
33
34 #ifndef NET_SOCKET_H
35 #define NET_SOCKET_H
36
37 #include <iostream>
38 #include "tConsole.h"
39 #include "tException.h"
40 #include <vector>
41
42 class nScoket;
43 struct nHostInfo;
44 // struct addrinfo;
45 struct hostentry;
46 struct sockaddr;
47
48 #ifdef WIN32
49 #include <winsock.h>
50 #else
51 #include <sys/socket.h>
52 #include <netinet/in.h>
53 #endif
54
55 typedef char int8;
56
57 //! union of supported internet addresses
58 union nAddressBase
59 {
60 struct sockaddr addr; //!< generic address
61 struct sockaddr_in addr_in; //!< IPV4 address
62 // struct sockaddr_in6 addr_in6; //!< IPV6 address ( not supported yet )
63 };
64
65 //! internet address
66 class nAddress
67 {
68 public:
69 nAddress(); //!< constructor
70 ~nAddress(); //!< destructor
71
72 // these functions handle address representation in the form hostname:port
73 nAddress const & ToString ( tString & string ) const ; //!< turns address to complete string
74 tString ToString () const ; //!< turns address to complete string
75 int FromString ( const char * string ) ; //!< turns complete string into address
76
77 // void FromAddrInfo( const addrinfo & info ) ; //!< copy address from addrinfo
78
79 void FromHostent ( int l, const char * addr ) ; //!< copy address from hostent data
80
81 nAddress & SetHostname ( const char * hostname ) ; //!< Sets the hostname part of the address (with DNS lookup)
82 tString GetHostname ( void ) const ; //!< Gets the hostname part of the address (with DNS lookup)
83 nAddress const & GetHostname ( tString & hostname ) const ; //!< Gets the hostname part of the address (with DNS lookup)
84
85 nAddress & SetAddress ( const char * address ) ; //!< Sets the hostname part of the address
86 tString GetAddress ( void ) const ; //!< Gets the hostname part of the address
87 nAddress const & GetAddress ( tString & address ) const ; //!< Gets the hostname part of the address
88
89 nAddress & SetPort ( int port ) ; //!< Sets the port of the address
90 int GetPort ( void ) const ; //!< Gets the port of the address
91 nAddress const & GetPort ( int & port ) const ; //!< Gets the port of the address
92
93 bool IsSet () const ; //!< returns true only if address is not INETADDR_ANY
94
95 static int Compare ( const nAddress & a1, const nAddress & a2 ); //!< compares two addresses
96
97 operator struct sockaddr * () { return &addr_.addr; } //!< conversion to sockaddr
98 operator struct sockaddr const *() const { return &addr_.addr; } //!< conversion to sockaddr
99
100 //! comparison operator
101 bool operator == ( nAddress const & other ) const
102 {
103 return Compare( *this, other ) == 0;
104 }
105
106 //! comparison operator
107 bool operator != ( nAddress const & other ) const
108 {
109 return Compare( *this, other ) != 0;
110 }
111
112 enum{ size = sizeof( nAddressBase ) };
113
114 unsigned int GetAddressLength( void ) const; //!< Gets the length of the stored address
115 private:
116 nAddressBase addr_; //!< the lowlevel network address
117 unsigned int addrLen_; //!< the length of the really stored address
118 };
119
120 //! wrapper for low level sockets.
121 class nSocket
122 {
123 public:
124 nSocket(); //!< constructor
125 ~nSocket(); //!< destructor
126
127 //! exception thrown on probably unrecoverable error
128 class PermanentError: public tException
129 {
130 public:
131 PermanentError(); //!< default constructor
132 PermanentError( const tString & details ); //!< constructor giving details on error
133 ~PermanentError(); //!< destructor
134 private:
135 virtual tString DoGetName() const; //!< returns the name of the exception
136 virtual tString DoGetDescription() const; //!< returns a detailed description
137
138 tString description_;
139 };
140
141 int Open (); //!< open socket for sending data ( not bound to a specific IP or port )
142 int Open ( nAddress const & address ); //!< open socket for listening on the specified address info
143 int Open ( int port ); //!< open socket for listening bound to the specified port
144 // int Open ( const addrinfo & addr ); //!< open socket for listening on the specified address info
145 int Open ( const nHostInfo & addr ); //!< open socket for listening on the specified host info
146 int Close (); //!< close the socket
147 bool IsOpen () const; //!< returns whether the socket is open
148 void Reset () const; //!< resets ( closes and reopens ) the socket
149
150 int Connect ( const nAddress & addr ); //!< connects the socket to the specified address
151 const nSocket * CheckNewConnection() const; //!< listens for new data
152
153 int Read ( int8 *buf, int len, nAddress & addr ) const; //!< reads data from the socket
154 int Write ( const int8 *buf, int len, const nAddress & addr ) const; //!< writes data to the socket
155 int Broadcast ( const char *buf, int len, unsigned int port ) const; //!< broadcasts data over the socket to the LAN
156
157 nAddress const & GetAddress( void ) const ; //!< Gets the address the socket is bound to
158 nSocket const & GetAddress( nAddress & address ) const ; //!< Gets the address the socket is bound to
159
160 inline int GetSocket( void ) const; //!< Gets the raw socket
161 inline nSocket const & GetSocket( int & socket ) const; //!< Gets the raw socket
162
163 // moving copy semantics
164 void MoveFrom( const nSocket & other ); //!< move data from other to this
165 nSocket( const nSocket & other ); //!< copy constructor. Warning: uses data move semantics
166 nSocket & operator=( const nSocket & other ); //!< copy operator. Warning: uses data move semantics
167 private:
168 int Create (); //!< creates the socket without binding it
169 int Bind ( nAddress const & address ); //!< binds the socket to a specific address
170
171 int Write ( const int8 *buf, int len, const sockaddr * addr, int addrlen ) const; //!< writes data to the socket
172
173 nSocket & SetAddress( nAddress const & address ); //!< Sets the address the socket is bound to
174 inline nSocket & SetSocket( int socket ); //!< Sets the raw socket
175
176 int socket_; //!< the raw socket
177 nAddress address_; //!< the address the socket is bound to
178 nAddress trueAddress_; //!< the address the socket is really bound to
179 int family_, socktype_, protocol_; //!< more low level data determining the socket type
180 mutable bool broadcast_; //!< flag indicating whether this socket has been prepared for broadcasts
181 };
182
183 //! collection of listening server sockets
184 class nSocketListener
185 {
186 public:
187 nSocketListener(); //!< constructor
188 ~nSocketListener(); //!< destructor
189
190 bool Listen ( bool state ); //!< enables/disables listening state
191
192 typedef std::vector< nSocket > SocketArray; //!< array of sockets
193 typedef SocketArray::const_iterator const_iterator; //!< iterator in that array
194 typedef SocketArray::const_iterator iterator; //!< iterator in that array
195
196 // almost std:: compliant iterator functions
197 iterator begin() const; //!< returns iterator to first socket
198 iterator end() const; //!< returns iterator to end of sockets
199
200 nSocketListener & SetPort ( unsigned int port ); //!< Sets the network port to listen on
201 unsigned int GetPort ( void ) const; //!< Gets the network port to listen on
202 nSocketListener const & GetPort ( unsigned int & port ) const; //!< Gets the network port to listen on
203 nSocketListener & SetIpList ( tString const & ipList ); //!< Sets list of IPs to bind to
204 tString const & GetIpList ( void ) const; //!< Gets list of IPs to bind to
205 nSocketListener const & GetIpList ( tString & ipList ) const; //!< Gets list of IPs to bind to
206 inline SocketArray const & GetSockets ( void ) const; //!< Gets the listening sockets
207 inline nSocketListener const & GetSockets ( SocketArray & sockets ) const; //!< Gets the listening sockets
208 private:
209 SocketArray sockets_; //!< the listening sockets
210 unsigned int port_; //!< the network port to listen on
211 tString ipList_; //!< list of IPs to bind to
212
213 // forbid copying
214 nSocketListener( const nSocketListener & );
215 nSocketListener & operator=( const nSocketListener & );
216
217 inline nSocketListener & SetSockets( SocketArray const & sockets ); //!< Sets the listening sockets
218 };
219
220 //! basic network system: manages sockets
221 class nBasicNetworkSystem
222 {
223 public:
224 nBasicNetworkSystem(); //!< constructor
225 ~nBasicNetworkSystem(); //!< destructor
226
227 nSocket* Init (void); //!< initializes the network
228 void Shutdown (void); //!< shuts donw the network
229
230 bool Select (REAL dt); //!< waits the specified time for data to arrive on the sockets
231
232 nSocketListener & AccessListener ( void ) ; //!< Accesses listening sockets
233 nBasicNetworkSystem & SetListener ( nSocketListener const & listener ) ; //!< Sets listening sockets
234 nSocketListener const & GetListener ( void ) const ; //!< Gets listening sockets
235 // nBasicNetworkSystem const & GetListener ( nSocketListener & listener ) const ; //!< Gets listening sockets
236
237 // nBasicNetworkSystem & SetControlSocket ( nSocket const & controlSocket ) ; //!< Sets network control socket
238 nSocket const & GetControlSocket ( void ) const ; //!< Gets network control socket
239 // nBasicNetworkSystem const & GetControlSocket ( nSocket & controlSocket ) const ; //!< Gets network control socket
240 private:
241
242 nSocketListener listener_; //!< listening sockets
243 nSocket controlSocket_; //!< network control socket
244
245 // forbid copying
246 nBasicNetworkSystem( const nBasicNetworkSystem & );
247 nBasicNetworkSystem & operator=( const nBasicNetworkSystem & );
248
249 nSocket & AccessControlSocket ( void ) ; //!< Accesses network control socket
250 };
251
252 // *******************************************************************************
253 // *
254 // * GetSockets
255 // *
256 // *******************************************************************************
257 //!
258 //! @return the listening sockets
259 //!
260 // *******************************************************************************
261
GetSockets(void)262 nSocketListener::SocketArray const & nSocketListener::GetSockets( void ) const
263 {
264 return this->sockets_;
265 }
266
267 // *******************************************************************************
268 // *
269 // * GetSockets
270 // *
271 // *******************************************************************************
272 //!
273 //! @param sockets the listening sockets to fill
274 //! @return A reference to this to allow chaining
275 //!
276 // *******************************************************************************
277
GetSockets(SocketArray & sockets)278 nSocketListener const & nSocketListener::GetSockets( SocketArray & sockets ) const
279 {
280 sockets = this->sockets_;
281 return *this;
282 }
283
284 // *******************************************************************************
285 // *
286 // * SetSockets
287 // *
288 // *******************************************************************************
289 //!
290 //! @param sockets the listening sockets to set
291 //! @return A reference to this to allow chaining
292 //!
293 // *******************************************************************************
294
SetSockets(SocketArray const & sockets)295 nSocketListener & nSocketListener::SetSockets( SocketArray const & sockets )
296 {
297 this->sockets_ = sockets;
298 return *this;
299 }
300
301 // *******************************************************************************
302 // *
303 // * GetSocket
304 // *
305 // *******************************************************************************
306 //!
307 //! @return the raw socket
308 //!
309 // *******************************************************************************
310
GetSocket(void)311 int nSocket::GetSocket( void ) const
312 {
313 return this->socket_;
314 }
315
316 // *******************************************************************************
317 // *
318 // * GetSocket
319 // *
320 // *******************************************************************************
321 //!
322 //! @param socket the raw socket to fill
323 //! @return A reference to this to allow chaining
324 //!
325 // *******************************************************************************
326
GetSocket(int & socket)327 nSocket const & nSocket::GetSocket( int & socket ) const
328 {
329 socket = this->socket_;
330 return *this;
331 }
332
333 // *******************************************************************************
334 // *
335 // * SetSocket
336 // *
337 // *******************************************************************************
338 //!
339 //! @param socket the raw socket to set
340 //! @return A reference to this to allow chaining
341 //!
342 // *******************************************************************************
343
SetSocket(int socket)344 nSocket & nSocket::SetSocket( int socket )
345 {
346 this->socket_ = socket;
347 return *this;
348 }
349
350 #endif
351