|
@@ -1,7 +1,6 @@
|
|
|
#include <iostream>
|
|
|
#include <cstring>
|
|
|
#include <vector>
|
|
|
-#include <atomic>
|
|
|
#include <thread>
|
|
|
#include <mutex>
|
|
|
|
|
@@ -11,8 +10,40 @@
|
|
|
#include <poll.h>
|
|
|
|
|
|
#include "server/network/Server.h"
|
|
|
+#include "server/network/Socket.h"
|
|
|
|
|
|
-static void printError(const char* message) {
|
|
|
+Server::Server(const Socket& connectionListener, u16 maxClients, GameServer& gameServer) :
|
|
|
+connectionListener(connectionListener), gameServer(gameServer), running(true),
|
|
|
+listenerThread(&Server::listenForClients, this) {
|
|
|
+ (void) maxClients;
|
|
|
+}
|
|
|
+
|
|
|
+Server::~Server() {
|
|
|
+ running = false;
|
|
|
+ listenerThread.join();
|
|
|
+}
|
|
|
+
|
|
|
+void Server::listenForClients() const {
|
|
|
+ while(running) {
|
|
|
+ WaitResult result = connectionListener.waitForConnection(100);
|
|
|
+ if(result == WaitResult::ERROR) {
|
|
|
+ break;
|
|
|
+ } else if(result == WaitResult::TIMEOUT) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ int clientSocket = connectionListener.acceptConnection();
|
|
|
+ if(clientSocket < 0) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ /*if(addClient(clientSocket)) {
|
|
|
+ if(close(clientSocket) == -1) {
|
|
|
+ printError("cannot close client socket");
|
|
|
+ }
|
|
|
+ }*/
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/*static void printError(const char* message) {
|
|
|
std::cout << message << ": " << strerror(errno) << "\n";
|
|
|
}
|
|
|
|
|
@@ -40,28 +71,16 @@ struct ConnectedClient {
|
|
|
};
|
|
|
|
|
|
struct InternServer final {
|
|
|
- InternServer() : listenerSocket(-1), listenerThread([]() {
|
|
|
- })
|
|
|
-, shouldRun(true), clients(nullptr) {
|
|
|
+
|
|
|
+ InternServer() : clients(nullptr) {
|
|
|
}
|
|
|
|
|
|
~InternServer() {
|
|
|
- shouldRun = false;
|
|
|
- listenerThread.join();
|
|
|
-
|
|
|
- if(listenerSocket != -1) {
|
|
|
- if(close(listenerSocket) == -1) {
|
|
|
- printError("cannot close listener socket");
|
|
|
- }
|
|
|
- }
|
|
|
if(clients != nullptr) {
|
|
|
delete[] clients;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- int listenerSocket;
|
|
|
- std::thread listenerThread;
|
|
|
- std::atomic_bool shouldRun;
|
|
|
ConnectedClient* clients;
|
|
|
};
|
|
|
|
|
@@ -84,8 +103,6 @@ static void defaultClientDisconnect(int) {
|
|
|
}
|
|
|
|
|
|
static std::mutex clientMutex;
|
|
|
-static u16 clientAmount = 0;
|
|
|
-static u16 maxClients = 0;
|
|
|
static Server::FullServerClientConnectFunction onFullServerClientConnect = defaultFullServerClientConnect;
|
|
|
static Server::ClientConnectFunction onClientConnect = defaultClientConnect;
|
|
|
static Server::ClientPackageFunction onClientPackage = defaultClientPackage;
|
|
@@ -114,7 +131,7 @@ static void listenOnClient(ConnectedClient& cc) {
|
|
|
fds.events = POLLIN; // wait until data is ready to read
|
|
|
fds.revents = 0; // return events - none
|
|
|
|
|
|
- onClientConnect(cc.socket);
|
|
|
+ //onClientConnect(cc.socket);
|
|
|
|
|
|
Stream st;
|
|
|
while(server.shouldRun) {
|
|
@@ -183,96 +200,4 @@ static bool addClient(int clientSocket) {
|
|
|
|
|
|
return false;
|
|
|
}
|
|
|
-}
|
|
|
-
|
|
|
-static void listenForClients() {
|
|
|
- while(server.shouldRun) {
|
|
|
- // wait until a connection arrives with timeout, this prevents being
|
|
|
- // stuck in accept
|
|
|
- struct pollfd fds;
|
|
|
- fds.fd = server.listenerSocket; // file descriptor for polling
|
|
|
- fds.events = POLLIN; // wait until data is ready to read
|
|
|
- fds.revents = 0; // return events - none
|
|
|
- // nfds_t - 1 - amount of passed in structs
|
|
|
- // timeout - 100 - milliseconds to wait until an event occurs
|
|
|
- // returns 0 on timeout, -1 on error, and >0 on success
|
|
|
- int pollData = poll(&fds, 1, 100);
|
|
|
- if(pollData > 0) {
|
|
|
- struct sockaddr_in clientSocketData;
|
|
|
- // accepts an incoming client connection and stores the data in the
|
|
|
- // given struct, returns a nonnegative file descriptor on success
|
|
|
- socklen_t addrlen = sizeof (struct sockaddr_in);
|
|
|
- int clientSocket = accept(server.listenerSocket, (struct sockaddr*) &clientSocketData, &addrlen);
|
|
|
- if(clientSocket >= 0) {
|
|
|
- if(addClient(clientSocket)) {
|
|
|
- if(close(clientSocket) == -1) {
|
|
|
- printError("cannot close client socket");
|
|
|
- }
|
|
|
- }
|
|
|
- } else {
|
|
|
- printError("accept error");
|
|
|
- break;
|
|
|
- }
|
|
|
- } else if(pollData == -1) {
|
|
|
- printError("poll error");
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-bool Server::start(u16 port, u16 inMaxClients) {
|
|
|
- // create socket for incoming connections
|
|
|
- // domain - AF_INET - IPv4 Internet protocols
|
|
|
- // type - SOCK_STREAM - two-way, connection-based byte streams
|
|
|
- // protocol - 0 - use standard protocol for the given socket type
|
|
|
- server.listenerSocket = socket(AF_INET, SOCK_STREAM, 0);
|
|
|
- if(server.listenerSocket == -1) {
|
|
|
- printError("cannot create listener socket");
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
- // prevents clients from blocking the port if the server exits
|
|
|
- // this is useful if server and client run on the same system
|
|
|
- struct linger sl;
|
|
|
- sl.l_onoff = 1; // nonzero to linger on close
|
|
|
- sl.l_linger = 0; // time to linger
|
|
|
- // sockfd - listenerSocket - modified socket
|
|
|
- // level - SOL_SOCKET - manipulate options at the sockets API level
|
|
|
- // optname - SO_LINGER - identifier of the option
|
|
|
- if(setsockopt(server.listenerSocket, SOL_SOCKET, SO_LINGER, &sl, sizeof (struct linger)) == -1) {
|
|
|
- printError("cannot set non lingering");
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
- // specify binding data
|
|
|
- struct sockaddr_in connectSocketData;
|
|
|
- // clear padding
|
|
|
- memset(&connectSocketData, 0, sizeof (struct sockaddr_in));
|
|
|
- // IPv4 Internet protocols
|
|
|
- connectSocketData.sin_family = AF_INET;
|
|
|
- // port in network byte order
|
|
|
- connectSocketData.sin_port = htons(port);
|
|
|
- // address in network byte order, accept any incoming messages
|
|
|
- connectSocketData.sin_addr.s_addr = htons(INADDR_ANY);
|
|
|
- // bind the socket
|
|
|
- if(bind(server.listenerSocket, (struct sockaddr*) &connectSocketData, sizeof (struct sockaddr_in)) == -1) {
|
|
|
- printError("cannot bind listener socket");
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
- // mark the socket as handler for connection requests
|
|
|
- // backlog - 5 - max queue length of pending connections
|
|
|
- if(listen(server.listenerSocket, 5) == -1) {
|
|
|
- printError("cannot start listening on socket");
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
- server.shouldRun = true;
|
|
|
-
|
|
|
- maxClients = inMaxClients;
|
|
|
- server.clients = new ConnectedClient[inMaxClients];
|
|
|
- // join empty spawn thread
|
|
|
- server.listenerThread.join();
|
|
|
- server.listenerThread = std::thread(listenForClients);
|
|
|
- return true;
|
|
|
-}
|
|
|
+}*/
|