Network.h 9.0 KB

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