TrinityCore
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
NetworkDevice.h
Go to the documentation of this file.
1 
39 #ifndef G3D_NETWORKDEVICE_H
40 #define G3D_NETWORKDEVICE_H
41 
42 #include "G3D/platform.h"
43 #include "G3D/NetAddress.h"
44 
45 #include <string>
46 #include <iostream>
47 #include "G3D/g3dmath.h"
48 
49 #include "G3D/ReferenceCount.h"
50 #include "G3D/Array.h"
51 #include "G3D/BinaryOutput.h"
52 
53 namespace G3D {
54 
55 class TextOutput;
58 protected:
59  friend class NetworkDevice;
60  friend class NetListener;
61 
66 
68 
74 
75  Conduit();
76 
77 public:
78 
79  virtual ~Conduit();
80  uint64 bytesSent() const;
81  uint64 messagesSent() const;
82  uint64 bytesReceived() const;
83  uint64 messagesReceived() const;
84 
88  virtual bool messageWaiting();
89 
130  virtual uint32 waitingMessageType() = 0;
131 
133  bool ok() const;
134 };
135 
136 typedef shared_ptr<class ReliableConduit> ReliableConduitRef;
137 
138 #ifdef __GNUC__
139 // Workaround for a known bug in gcc 4.x where htonl produces
140 // a spurrious warning.
141 // http://gcc.gnu.org/ml/gcc-bugs/2005-10/msg03270.html
142 uint32 gcchtonl(uint32);
143 #endif
144 
145 // Messaging and stream APIs must be supported on a single class because
146 // sometimes an application will switch modes on a single socket. For
147 // example, when transferring 3D level geometry during handshaking with
148 // a game server.
168 class ReliableConduit : public Conduit {
169 private:
170  friend class NetworkDevice;
171  friend class NetListener;
172 
174 
176 
181 
186 
189 
192 
197 
198  ReliableConduit(const NetAddress& addr);
199 
200  ReliableConduit(const SOCKET& sock,
201  const NetAddress& addr);
202 
203  template<typename T> static void serializeMessage
204  (uint32 t, const T& m, BinaryOutput& b) {
205 
206  b.writeUInt32(t);
207 
208  // Reserve space for the 4 byte size header
209  b.writeUInt32(0);
210 
211  size_t L = (size_t)b.length();
212  m.serialize(b);
213  if ((size_t)b.length() == L) {
214  // No data was created by serialization.
215  // We need to send at least one byte because receive assumes that
216  // a zero length message is an error.
217  b.writeUInt8(0xFF);
218  }
219 
220  uint32 len = (uint32)b.size() - 8;
221 
222  // We send the length first to tell recv how much data to read.
223  // Here we abuse BinaryOutput a bit and write directly into
224  // its buffer, violating the abstraction.
225  // Note that we write to the second set of 4 bytes, which is
226  // the size field.
227  uint32* lenPtr = ((uint32*)b.getCArray()) + 1;
228  #if defined(__GNUC__)
229  *lenPtr = gcchtonl(len);
230  #else
231  *lenPtr = htonl(len);
232  #endif
233  }
234 
235 
236  void sendBuffer(const BinaryOutput& b);
237 
243  void receiveIntoBuffer();
244 
246  void receiveHeader();
247 
248 public:
249 
254  static ReliableConduitRef create(const NetAddress& address);
255 
258 
259 
262  virtual bool messageWaiting();
263 
277  template<typename T> inline void send(uint32 type, const T& message) {
279  serializeMessage(type, message, binaryOutput);
281  }
282 
285  void send(uint32 type);
286 
289  template<typename T>
290  inline static void multisend(
291  const Array<ReliableConduitRef>& array,
292  uint32 type,
293  const T& m) {
294 
295  if (array.size() > 0) {
296  array[0]->binaryOutput.reset();
297  serializeMessage(type, m, array[0]->binaryOutput);
298 
299  for (int i = 0; i < array.size(); ++i) {
300  array[i]->sendBuffer(array[0]->binaryOutput);
301  }
302  }
303  }
304 
305  virtual uint32 waitingMessageType();
306 
313  template<typename T> inline bool receive(T& message) {
314  if (! messageWaiting()) {
315  return false;
316  }
317 
319  // Deserialize
320  BinaryInput b((uint8*)receiveBuffer, receiveBufferUsedSize, G3D_LITTLE_ENDIAN, BinaryInput::NO_COPY);
321  message.deserialize(b);
322 
323  // Don't let anyone read this message again. We leave the buffer
324  // allocated for the next caller, however.
325  receiveBufferUsedSize = 0;
326  state = NO_MESSAGE;
327  messageType = 0;
328  messageSize = 0;
329 
330  // Potentially read the next message.
331  messageWaiting();
332 
333  return true;
334  }
335 
337  inline void receive() {
338  if (! messageWaiting()) {
339  return;
340  }
341  receiveBufferUsedSize = 0;
342  state = NO_MESSAGE;
343  messageType = 0;
344  messageSize = 0;
345 
346  // Potentially read the next message.
347  messageWaiting();
348  }
349 
351  NetAddress address() const;
352 };
353 
354 
355 typedef shared_ptr<class LightweightConduit> LightweightConduitRef;
356 
407 class LightweightConduit : public Conduit {
408 private:
409  friend class NetworkDevice;
410 
416 
421 
426 
431 
432  LightweightConduit(uint16 receivePort, bool enableReceive, bool enableBroadcast);
433 
434  void sendBuffer(const NetAddress& a, BinaryOutput& b);
435 
438  int MTU;
439 
440 
441  template<typename T>
443  uint32 type,
444  const T& m,
445  BinaryOutput& b) const {
446 
447  debugAssert(type != 0);
448  b.writeUInt32(type);
449  m.serialize(b);
450  b.writeUInt32(1);
451 
452  debugAssertM(b.size() < MTU,
453  format("This LightweightConduit is limited to messages of "
454  "%d bytes (Ethernet hardware limit; this is the "
455  "'UDP MTU')", maxMessageSize()));
456 
457  if (b.size() >= MTU) {
459  format("This LightweightConduit is limited to messages of "
460  "%d bytes (Ethernet hardware limit; this is the "
461  "'UDP MTU')", maxMessageSize()),
462  (int)b.size() - 4, // Don't count the type header
463  maxMessageSize());
464  }
465  }
466 
467 public:
468 
469  static LightweightConduitRef create(uint16 receivePort, bool enableReceive, bool enableBroadcast);
470 
472  public:
473  std::string message;
476 
477  inline PacketSizeException(const std::string& m, int s, int b) :
478  message(m),
479  serializedPacketSize(s),
480  maxMessageSize(b) {}
481  };
482 
485 
490  inline int maxMessageSize() const {
491  return MTU - 4;
492  }
493 
494 
495  template<typename T> inline void send(const NetAddress& a, uint32 type, const T& msg) {
497  serializeMessage(type, msg, binaryOutput);
499  }
500 
504  template<typename T> inline void send(const Array<NetAddress>& a, uint32 type, const T& m) {
506  serializeMessage(type, m, binaryOutput);
507 
508  for (int i = 0; i < a.size(); ++i) {
509  sendBuffer(a[i], binaryOutput);
510  }
511  }
512 
513  bool receive(NetAddress& sender);
514 
515  template<typename T> inline bool receive(NetAddress& sender, T& message) {
516  bool r = receive(sender);
517  if (r) {
518  BinaryInput b((messageBuffer.getCArray() + 4),
519  messageBuffer.size() - 4,
521  message.deserialize(b);
522  }
523 
524  return r;
525  }
526 
527  inline bool receive() {
528  static NetAddress ignore;
529  return receive(ignore);
530  }
531 
532  virtual uint32 waitingMessageType();
533 
534 
535  virtual bool messageWaiting();
536 };
537 
539 
540 typedef shared_ptr<class NetListener> NetListenerRef;
541 
548 private:
549 
550  friend class NetworkDevice;
551 
553 
555  NetListener(uint16 port);
556 
557 public:
558 
559  static NetListenerRef create(const uint16 port);
560 
561  ~NetListener();
562 
565  ReliableConduitRef waitForConnection();
566 
569  bool clientWaiting() const;
570 
571  bool ok() const;
572 };
573 
574 
576 
609 public:
610 
613  public:
615  std::string hostname;
616 
618  std::string name;
619 
622 
625 
628 
630  uint8 mac[6];
631 
632  EthernetAdapter();
633 
635  void describe(TextOutput& t) const;
636  };
637 
638 private:
639 
640  friend class Conduit;
641  friend class LightweightConduit;
642  friend class ReliableConduit;
643  friend class NetListener;
644 
646 
648 
652 
654  void closesocket(SOCKET& sock) const;
655 
657  bool bind(SOCKET sock, const NetAddress& addr) const;
658 
661 
662  NetworkDevice();
663 
664  bool init();
665 
666  void _cleanup();
667 
670  void addAdapter(const EthernetAdapter& a);
671 
672 public:
673 
676  static std::string formatIP(uint32 ip);
677 
679  static std::string formatMAC(const uint8 mac[6]);
680 
681  ~NetworkDevice();
682 
686  inline const Array<EthernetAdapter>& adapterArray() const {
687  return m_adapterArray;
688  }
689 
692  inline const Array<uint32>& broadcastAddressArray() const {
693  return m_broadcastAddresses;
694  }
695 
699  static NetworkDevice* instance();
700 
704  static void cleanup();
705 
710  void describeSystem(
711  TextOutput& t);
712 
713  void describeSystem(
714  std::string& s);
715 
717  std::string localHostName() const;
718 
723  void localHostAddresses(Array<NetAddress>& array) const;
724 };
725 
726 
727 #ifdef __GNUC__
728 inline uint32 gcchtonl(uint32 x) {
729  // This pragma fools gcc into surpressing all error messages,
730  // including the bogus one that it creates for htonl
731 # pragma GCC system_header
732  return htonl(x);
733 }
734 #endif
735 
736 } // G3D namespace
737 
738 #ifndef _WIN32
739 #undef SOCKADDR_IN
740 #undef SOCKET
741 #endif
742 
743 #endif
static LightweightConduitRef create(uint16 receivePort, bool enableReceive, bool enableBroadcast)
Definition: NetworkDevice.cpp:989
Conduit()
Definition: NetworkDevice.cpp:540
bool bind(SOCKET sock, const NetAddress &addr) const
Definition: NetworkDevice.cpp:484
void describe(TextOutput &t) const
Definition: NetworkDevice.cpp:188
uint32 messageSize
Definition: NetworkDevice.h:185
SOCKET sock
Definition: NetworkDevice.h:552
void receiveHeader()
Definition: NetworkDevice.cpp:875
LightweightConduit(uint16 receivePort, bool enableReceive, bool enableBroadcast)
Definition: NetworkDevice.cpp:999
std::string hostname
Definition: NetworkDevice.h:615
uint32 broadcast
Definition: NetworkDevice.h:627
uint64 bSent
Definition: NetworkDevice.h:64
void closesocket(SOCKET &sock) const
Definition: NetworkDevice.cpp:501
void send(const NetAddress &a, uint32 type, const T &msg)
Definition: NetworkDevice.h:495
std::string name
Definition: NetworkDevice.h:618
Array< EthernetAdapter > m_adapterArray
Definition: NetworkDevice.h:647
static NetListenerRef create(const uint16 port)
Definition: NetworkDevice.cpp:1146
bool initialized
Definition: NetworkDevice.h:645
void addAdapter(const EthernetAdapter &a)
Definition: NetworkDevice.cpp:223
int serializedPacketSize
Definition: NetworkDevice.h:474
uint64 messagesSent() const
Definition: NetworkDevice.cpp:564
Definition: NetworkDevice.h:57
const Array< EthernetAdapter > & adapterArray() const
Definition: NetworkDevice.h:686
virtual uint32 waitingMessageType()
Definition: NetworkDevice.cpp:1093
void send(uint32 type, const T &message)
Definition: NetworkDevice.h:277
State
Definition: NetworkDevice.h:173
Definition: BinaryInput.h:69
Definition: NetworkDevice.h:173
std::string message
Definition: NetworkDevice.h:473
void sendBuffer(const BinaryOutput &b)
Definition: NetworkDevice.cpp:836
void describeSystem(TextOutput &t)
Definition: NetworkDevice.cpp:1254
size_t receiveBufferTotalSize
Definition: NetworkDevice.h:191
static ReliableConduitRef create(const NetAddress &address)
Definition: NetworkDevice.cpp:611
bool clientWaiting() const
Definition: NetworkDevice.cpp:1248
Array< uint32 > m_broadcastAddresses
Definition: NetworkDevice.h:651
virtual bool messageWaiting()
Definition: NetworkDevice.cpp:776
int64 size() const
Definition: BinaryOutput.h:200
void receiveIntoBuffer()
Definition: NetworkDevice.cpp:937
T * getCArray()
Definition: Array.h:256
Definition: AABox.h:25
Dynamic 1D array tuned for performance.
Definition: Array.h:95
bool ok() const
Definition: NetworkDevice.cpp:574
void writeUInt8(uint8 i)
Definition: BinaryOutput.h:283
shared_ptr< class LightweightConduit > LightweightConduitRef
Definition: NetworkDevice.h:355
const uint8 * getCArray() const
Definition: BinaryOutput.h:153
uint64 mSent
Definition: NetworkDevice.h:62
~LightweightConduit()
Definition: NetworkDevice.cpp:1047
Definition: NetAddress.h:18
uint64_t uint64
Definition: g3dmath.h:170
void reset()
Definition: BinaryOutput.cpp:240
uint64 bytesReceived() const
Definition: NetworkDevice.cpp:559
virtual bool messageWaiting()
Definition: NetworkDevice.cpp:1087
void send(const Array< NetAddress > &a, uint32 type, const T &m)
Definition: NetworkDevice.h:504
static void multisend(const Array< ReliableConduitRef > &array, uint32 type, const T &m)
Definition: NetworkDevice.h:290
#define debugAssertM(exp, message)
Definition: debugAssert.h:161
uint16_t uint16
Definition: g3dmath.h:166
SOCKET sock
Definition: NetworkDevice.h:67
~NetListener()
Definition: NetworkDevice.cpp:1204
Definition: NetworkDevice.h:173
std::string localHostName() const
Definition: NetworkDevice.cpp:139
static NetworkDevice * s_instance
Definition: NetworkDevice.h:660
Definition: NetworkDevice.h:471
~ReliableConduit()
Definition: NetworkDevice.cpp:768
uint32 ip
Definition: NetworkDevice.h:621
Definition: ReferenceCount.h:24
NetAddress addr
Definition: NetworkDevice.h:175
uint64 bytesSent() const
Definition: NetworkDevice.cpp:554
Array< uint8 > messageBuffer
Definition: NetworkDevice.h:430
void localHostAddresses(Array< NetAddress > &array) const
Definition: NetworkDevice.cpp:515
bool receive()
Definition: NetworkDevice.h:527
Abstraction of network (socket) functionality.
Definition: NetworkDevice.h:608
NetAddress messageSender
Definition: NetworkDevice.h:420
NetAddress address() const
Definition: NetworkDevice.cpp:870
#define debugAssert(exp)
Definition: debugAssert.h:160
shared_ptr< class NetListener > NetListenerRef
Definition: NetworkDevice.h:540
uint32 subnet
Definition: NetworkDevice.h:624
Description of an ethernet or wireless ethernet adapter.
Definition: NetworkDevice.h:612
virtual uint32 waitingMessageType()=0
static std::string formatMAC(const uint8 mac[6])
Definition: NetworkDevice.cpp:240
uint32_t uint32
Definition: Define.h:150
uint8 mac[6]
Definition: NetworkDevice.h:630
PacketSizeException(const std::string &m, int s, int b)
Definition: NetworkDevice.h:477
void _cleanup()
Definition: NetworkDevice.cpp:475
void * receiveBuffer
Definition: NetworkDevice.h:188
enum G3D::ReliableConduit::State state
std::string __cdecl format(const char *fmt...) G3D_CHECK_PRINTF_ARGS
static const bool NO_COPY
Definition: BinaryInput.h:147
int maxMessageSize() const
Definition: NetworkDevice.h:490
int size() const
Definition: Array.h:430
BinaryOutput binaryOutput
Definition: NetworkDevice.h:73
uint32 messageType
Definition: NetworkDevice.h:180
Definition: TextOutput.h:60
uint32 messageType
Definition: NetworkDevice.h:425
Definition: NetworkDevice.h:173
bool ok() const
Definition: NetworkDevice.cpp:1243
const Array< uint32 > & broadcastAddressArray() const
Definition: NetworkDevice.h:692
NetworkDevice()
Definition: NetworkDevice.cpp:130
void receive()
Definition: NetworkDevice.h:337
uint8_t uint8
Definition: g3dmath.h:164
void serializeMessage(uint32 type, const T &m, BinaryOutput &b) const
Definition: NetworkDevice.h:442
virtual uint32 waitingMessageType()
Definition: NetworkDevice.cpp:826
virtual bool messageWaiting()
Definition: NetworkDevice.cpp:579
Definition: System.h:50
Definition: BinaryOutput.h:52
Definition: NetworkDevice.h:547
NetListener(uint16 port)
Definition: NetworkDevice.cpp:1151
virtual ~Conduit()
Definition: NetworkDevice.cpp:549
Definition: NetworkDevice.h:407
uint64 bReceived
Definition: NetworkDevice.h:65
bool receive(NetAddress &sender, T &message)
Definition: NetworkDevice.h:515
shared_ptr< class ReliableConduit > ReliableConduitRef
Definition: NetworkDevice.h:136
void writeUInt32(uint32 u)
Definition: BinaryOutput.cpp:395
uint32_t uint32
Definition: g3dmath.h:168
G3D::int16 x
Definition: Vector2int16.h:37
Definition: NetworkDevice.h:168
ReliableConduitRef waitForConnection()
Definition: NetworkDevice.cpp:1210
int MTU
Definition: NetworkDevice.h:438
~NetworkDevice()
Definition: NetworkDevice.cpp:135
size_t receiveBufferUsedSize
Definition: NetworkDevice.h:196
static void cleanup()
Definition: NetworkDevice.cpp:121
static void serializeMessage(uint32 t, const T &m, BinaryOutput &b)
Definition: NetworkDevice.h:204
uint64 mReceived
Definition: NetworkDevice.h:63
#define SOCKET
Definition: netheaders.h:20
static std::string formatIP(uint32 ip)
Definition: NetworkDevice.cpp:234
static NetworkDevice * instance()
Definition: NetworkDevice.cpp:109
uint64 messagesReceived() const
Definition: NetworkDevice.cpp:569
ReliableConduit(const NetAddress &addr)
Definition: NetworkDevice.cpp:617
int maxMessageSize
Definition: NetworkDevice.h:475
EthernetAdapter()
Definition: NetworkDevice.cpp:177
bool alreadyReadMessage
Definition: NetworkDevice.h:415
void sendBuffer(const NetAddress &a, BinaryOutput &b)
Definition: NetworkDevice.cpp:1072
bool receive(T &message)
Definition: NetworkDevice.h:313
int64 length() const
Definition: BinaryOutput.h:196