| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188 |
- /* Copyright The kNet Project.
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License. */
- #pragma once
- /** @file Network.h
- @brief The class Network. The root point for creating client and server objects. */
- // Modified by Lasse Oorni for Urho3D
- #if defined(KNET_UNIX) || defined(ANDROID)
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <netdb.h>
- // Urho3D: include also unistd.h
- #include <unistd.h>
- #endif
- #include "kNetBuildConfig.h"
- #include "Socket.h"
- #include "NetworkServer.h"
- #include "MessageConnection.h"
- #include "StatsEventHierarchy.h"
- namespace kNet
- {
- class NetworkWorkerThread;
- /// Provides the application an interface for both client and server networking.
- class Network
- {
- public:
- Network();
- ~Network();
- static void PrintAddrInfo(const addrinfo *address);
- void PrintHostNameInfo(const char *hostname, const char *port);
- /// Starts a network server that listens to the given local port.
- /// @param serverListener [in] A pointer to the listener object that will be registered to receive notifications
- /// about incoming connections.
- /// @param allowAddressReuse If true, kNet passes the SO_REUSEADDR parameter to the server listen socket before binding
- /// the socket to a local port (== before starting the server). This allows the same port to be forcibly reused
- /// when restarting the server if a crash occurs, without having to wait for the operating system to free up the port.
- NetworkServer *StartServer(unsigned short port, SocketTransportLayer transport, INetworkServerListener *serverListener, bool allowAddressReuse);
- /// Starts a network server that listens to multiple local ports.
- /// This version of the function is given a list of pairs (port, UDP|TCP) values
- /// and the server will start listening on each of them.
- /// @param allowAddressReuse If true, kNet passes the SO_REUSEADDR parameter to the server listen socket before binding
- /// the socket to a local port (== before starting the server). This allows the same port to be forcibly reused
- /// when restarting the server if a crash occurs, without having to wait for the operating system to free up the port.
- NetworkServer *StartServer(const std::vector<std::pair<unsigned short, SocketTransportLayer> > &listenPorts, INetworkServerListener *serverListener, bool allowAddressReuse);
- void StopServer();
- /// Connects a raw socket (low-level, no MessageConnection abstraction) to the given destination.
- Socket *ConnectSocket(const char *address, unsigned short port, SocketTransportLayer transport);
- /// Frees the given Socket object (performs an immediate bidirectional shutdown and frees the socket). After calling
- /// this function, do not dereference that Socket pointer, as it is deleted.
- void DeleteSocket(Socket *socket);
- /// Closes the given MessageConnection object.
- void CloseConnection(MessageConnection *connection);
- /** Connects to the given address:port using kNet over UDP or TCP. When you are done with the connection,
- free it by letting the refcount go to 0. */
- Ptr(MessageConnection) Connect(const char *address, unsigned short port, SocketTransportLayer transport, IMessageHandler *messageHandler, Datagram *connectMessage = 0);
- /// Returns the local host name of the system (the local machine name or the local IP, whatever is specified by the system).
- const char *LocalAddress() const { return localHostName.c_str(); }
- /// Returns the error string associated with the given networking error id.
- static std::string GetErrorString(int error);
- /// Returns the error string corresponding to the last error that occurred in the networking library.
- static std::string GetLastErrorString();
- /// Returns the error id corresponding to the last error that occurred in the networking library.
- static int GetLastError();
- /// Returns the amount of currently executing background network worker threads.
- int NumWorkerThreads() const { return (int)workerThreads.size(); }
- /// Returns the NetworkServer object, or null if no server has been started.
- Ptr(NetworkServer) GetServer() { return server; }
- /// Returns all current connections in the system.
- std::set<MessageConnection *> Connections() const { return connections; }
- /// Returns the data structure that collects statistics about the whole Network.
- Lock<StatsEventHierarchyNode> Statistics() { return statistics.Acquire(); }
- private:
- /// Specifies the local network address of the system. This name is cached here on initialization
- /// to avoid multiple queries to namespace providers whenever the name is needed.
- std::string localHostName;
- /// Maintains the server-related data structures if this computer
- /// is acting as a server. Otherwise this data is not used.
- Ptr(NetworkServer) server;
- /// Contains all active sockets in the system.
- std::list<Socket> sockets;
- /// Tracks all existing connections in the system.
- std::set<MessageConnection *> connections;
- Lockable<StatsEventHierarchyNode> statistics;
- /// Takes the ownership of the given socket, and returns a pointer to the owned one.
- Socket *StoreSocket(const Socket &cp);
- friend class NetworkServer;
- void SendUDPConnectDatagram(Socket &socket, Datagram *connectMessage);
- /// Returns a new UDP socket that is bound to communicating with the given endpoint, under
- /// the given UDP master server socket.
- /// The returned pointer is owned by this class.
- Socket *CreateUDPSlaveSocket(Socket *serverListenSocket, const EndPoint &remoteEndPoint, const char *remoteHostName);
- /// Opens a new socket that listens on the given port using the given transport.
- /// @param allowAddressReuse If true, kNet passes the SO_REUSEADDR parameter to the server listen socket before binding
- /// the socket to a local port (== before starting the server). This allows the same port to be forcibly reused
- /// when restarting the server if a crash occurs, without having to wait for the operating system to free up the port.
- Socket *OpenListenSocket(unsigned short port, SocketTransportLayer transport, bool allowAddressReuse);
- /// Stores all the currently running network worker threads. Each thread is assigned
- /// a list of MessageConnections and NetworkServers to oversee. The worker threads
- /// then manage the socket reads and writes on these connections.
- std::vector<NetworkWorkerThread*> workerThreads;
- /// Examines each currently running worker thread and returns one that has sufficiently low load,
- /// or creates a new thread and returns it if no such thread exists. The thread is added and maintained
- /// in the workerThreads list.
- NetworkWorkerThread *GetOrCreateWorkerThread();
- /// A notification function that is called by NetworkServer whenever it creates a new MessageConnection object.
- /// The Network subsystem will store this new connection for tracking purposes.
- void NewMessageConnectionCreated(MessageConnection *connection);
- /// Takes the given MessageConnection and associates a NetworkWorkerThread for it.
- void AssignConnectionToWorkerThread(MessageConnection *connection);
- /// Takes the given server and associates a NetworkWorkerThread for it.
- void AssignServerToWorkerThread(NetworkServer *server);
- /// Closes the given workerThread and deletes it (do not reference the passed pointer afterwards).
- /// Call this function only after first removing all MessageConnections and NetworkServers from the thread.
- void CloseWorkerThread(NetworkWorkerThread *workerThread);
- /// Dissociates the given connection from its worker thread, and closes the worker thread if it does not
- /// have any servers or connections to work on any more.
- void RemoveConnectionFromItsWorkerThread(MessageConnection *connection);
- /// Dissociates the given server from its worker thread, and closes the worker thread if it does not
- /// have any servers or connections to work on any more.
- void RemoveServerFromItsWorkerThread(NetworkServer *server);
- void Init();
- void DeInit();
- #ifdef WIN32
- WSADATA wsaData;
- #endif
- };
- /// Outputs the given number of bytes formatted to KB or MB suffix for readability.
- std::string FormatBytes(u64 numBytes);
- std::string FormatBytes(double numBytes);
- } // ~kNet
|