Network.h 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. /* Copyright The kNet Project.
  2. Licensed under the Apache License, Version 2.0 (the "License");
  3. you may not use this file except in compliance with the License.
  4. You may obtain a copy of the License at
  5. http://www.apache.org/licenses/LICENSE-2.0
  6. Unless required by applicable law or agreed to in writing, software
  7. distributed under the License is distributed on an "AS IS" BASIS,
  8. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  9. See the License for the specific language governing permissions and
  10. limitations under the License. */
  11. #pragma once
  12. /** @file Network.h
  13. @brief The class Network. The root point for creating client and server objects. */
  14. // Modified by Lasse Oorni for Urho3D
  15. #if defined(KNET_UNIX) || defined(ANDROID)
  16. #include <sys/types.h>
  17. #include <sys/socket.h>
  18. #include <netinet/in.h>
  19. #include <netdb.h>
  20. // Urho3D: include also unistd.h
  21. #include <unistd.h>
  22. #endif
  23. #include "kNetBuildConfig.h"
  24. #include "Socket.h"
  25. #include "NetworkServer.h"
  26. #include "MessageConnection.h"
  27. #include "StatsEventHierarchy.h"
  28. namespace kNet
  29. {
  30. class NetworkWorkerThread;
  31. /// Provides the application an interface for both client and server networking.
  32. class Network
  33. {
  34. public:
  35. Network();
  36. ~Network();
  37. static void PrintAddrInfo(const addrinfo *address);
  38. void PrintHostNameInfo(const char *hostname, const char *port);
  39. /// Starts a network server that listens to the given local port.
  40. /// @param serverListener [in] A pointer to the listener object that will be registered to receive notifications
  41. /// about incoming connections.
  42. /// @param allowAddressReuse If true, kNet passes the SO_REUSEADDR parameter to the server listen socket before binding
  43. /// the socket to a local port (== before starting the server). This allows the same port to be forcibly reused
  44. /// when restarting the server if a crash occurs, without having to wait for the operating system to free up the port.
  45. NetworkServer *StartServer(unsigned short port, SocketTransportLayer transport, INetworkServerListener *serverListener, bool allowAddressReuse);
  46. /// Starts a network server that listens to multiple local ports.
  47. /// This version of the function is given a list of pairs (port, UDP|TCP) values
  48. /// and the server will start listening on each of them.
  49. /// @param allowAddressReuse If true, kNet passes the SO_REUSEADDR parameter to the server listen socket before binding
  50. /// the socket to a local port (== before starting the server). This allows the same port to be forcibly reused
  51. /// when restarting the server if a crash occurs, without having to wait for the operating system to free up the port.
  52. NetworkServer *StartServer(const std::vector<std::pair<unsigned short, SocketTransportLayer> > &listenPorts, INetworkServerListener *serverListener, bool allowAddressReuse);
  53. void StopServer();
  54. /// Connects a raw socket (low-level, no MessageConnection abstraction) to the given destination.
  55. Socket *ConnectSocket(const char *address, unsigned short port, SocketTransportLayer transport);
  56. /// Frees the given Socket object (performs an immediate bidirectional shutdown and frees the socket). After calling
  57. /// this function, do not dereference that Socket pointer, as it is deleted.
  58. void DeleteSocket(Socket *socket);
  59. /// Closes the given MessageConnection object.
  60. void CloseConnection(MessageConnection *connection);
  61. /** Connects to the given address:port using kNet over UDP or TCP. When you are done with the connection,
  62. free it by letting the refcount go to 0. */
  63. Ptr(MessageConnection) Connect(const char *address, unsigned short port, SocketTransportLayer transport, IMessageHandler *messageHandler, Datagram *connectMessage = 0);
  64. /// Returns the local host name of the system (the local machine name or the local IP, whatever is specified by the system).
  65. const char *LocalAddress() const { return localHostName.c_str(); }
  66. /// Returns the error string associated with the given networking error id.
  67. static std::string GetErrorString(int error);
  68. /// Returns the error string corresponding to the last error that occurred in the networking library.
  69. static std::string GetLastErrorString();
  70. /// Returns the error id corresponding to the last error that occurred in the networking library.
  71. static int GetLastError();
  72. /// Returns the amount of currently executing background network worker threads.
  73. int NumWorkerThreads() const { return (int)workerThreads.size(); }
  74. /// Returns the NetworkServer object, or null if no server has been started.
  75. Ptr(NetworkServer) GetServer() { return server; }
  76. /// Returns all current connections in the system.
  77. std::set<MessageConnection *> Connections() const { return connections; }
  78. /// Returns the data structure that collects statistics about the whole Network.
  79. Lock<StatsEventHierarchyNode> Statistics() { return statistics.Acquire(); }
  80. private:
  81. /// Specifies the local network address of the system. This name is cached here on initialization
  82. /// to avoid multiple queries to namespace providers whenever the name is needed.
  83. std::string localHostName;
  84. /// Maintains the server-related data structures if this computer
  85. /// is acting as a server. Otherwise this data is not used.
  86. Ptr(NetworkServer) server;
  87. /// Contains all active sockets in the system.
  88. std::list<Socket> sockets;
  89. /// Tracks all existing connections in the system.
  90. std::set<MessageConnection *> connections;
  91. Lockable<StatsEventHierarchyNode> statistics;
  92. /// Takes the ownership of the given socket, and returns a pointer to the owned one.
  93. Socket *StoreSocket(const Socket &cp);
  94. friend class NetworkServer;
  95. void SendUDPConnectDatagram(Socket &socket, Datagram *connectMessage);
  96. /// Returns a new UDP socket that is bound to communicating with the given endpoint, under
  97. /// the given UDP master server socket.
  98. /// The returned pointer is owned by this class.
  99. Socket *CreateUDPSlaveSocket(Socket *serverListenSocket, const EndPoint &remoteEndPoint, const char *remoteHostName);
  100. /// Opens a new socket that listens on the given port using the given transport.
  101. /// @param allowAddressReuse If true, kNet passes the SO_REUSEADDR parameter to the server listen socket before binding
  102. /// the socket to a local port (== before starting the server). This allows the same port to be forcibly reused
  103. /// when restarting the server if a crash occurs, without having to wait for the operating system to free up the port.
  104. Socket *OpenListenSocket(unsigned short port, SocketTransportLayer transport, bool allowAddressReuse);
  105. /// Stores all the currently running network worker threads. Each thread is assigned
  106. /// a list of MessageConnections and NetworkServers to oversee. The worker threads
  107. /// then manage the socket reads and writes on these connections.
  108. std::vector<NetworkWorkerThread*> workerThreads;
  109. /// Examines each currently running worker thread and returns one that has sufficiently low load,
  110. /// or creates a new thread and returns it if no such thread exists. The thread is added and maintained
  111. /// in the workerThreads list.
  112. NetworkWorkerThread *GetOrCreateWorkerThread();
  113. /// A notification function that is called by NetworkServer whenever it creates a new MessageConnection object.
  114. /// The Network subsystem will store this new connection for tracking purposes.
  115. void NewMessageConnectionCreated(MessageConnection *connection);
  116. /// Takes the given MessageConnection and associates a NetworkWorkerThread for it.
  117. void AssignConnectionToWorkerThread(MessageConnection *connection);
  118. /// Takes the given server and associates a NetworkWorkerThread for it.
  119. void AssignServerToWorkerThread(NetworkServer *server);
  120. /// Closes the given workerThread and deletes it (do not reference the passed pointer afterwards).
  121. /// Call this function only after first removing all MessageConnections and NetworkServers from the thread.
  122. void CloseWorkerThread(NetworkWorkerThread *workerThread);
  123. /// Dissociates the given connection from its worker thread, and closes the worker thread if it does not
  124. /// have any servers or connections to work on any more.
  125. void RemoveConnectionFromItsWorkerThread(MessageConnection *connection);
  126. /// Dissociates the given server from its worker thread, and closes the worker thread if it does not
  127. /// have any servers or connections to work on any more.
  128. void RemoveServerFromItsWorkerThread(NetworkServer *server);
  129. void Init();
  130. void DeInit();
  131. #ifdef WIN32
  132. WSADATA wsaData;
  133. #endif
  134. };
  135. /// Outputs the given number of bytes formatted to KB or MB suffix for readability.
  136. std::string FormatBytes(u64 numBytes);
  137. std::string FormatBytes(double numBytes);
  138. } // ~kNet