123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202 |
- #include <iostream>
- #include <cstring>
- #include <thread>
- #include <mutex>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <unistd.h>
- #include <poll.h>
- #include "server/network/Server.h"
- #include "server/network/Socket.h"
- 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";
- }
- struct ConnectedClient final {
- ~ConnectedClient() {
- if(socket != -1) {
- if(shutdown(socket, SHUT_RDWR)) {
- printError("cannot shutdown client socket");
- }
- if(close(socket) == -1) {
- printError("cannot close client socket");
- }
- }
- if(th.joinable()) {
- th.join();
- } else {
- std::cout << "cannot join client connection thread\n";
- }
- }
- std::thread th = std::thread([]() {
- });
- int socket = -1;
- };
- struct InternServer final {
- InternServer() : clients(nullptr) {
- }
- ~InternServer() {
- if(clients != nullptr) {
- delete[] clients;
- }
- }
- ConnectedClient* clients;
- };
- static InternServer server;
- static void defaultFullServerClientConnect(int) {
- std::cout << "default onFullServerClientConnectFunction\n";
- }
- static void defaultClientConnect(int) {
- std::cout << "default onClientConnectFunction\n";
- }
- static void defaultClientPackage(int, Stream&) {
- std::cout << "default onClientPackageFunction\n";
- }
- static void defaultClientDisconnect(int) {
- std::cout << "default onClientDisconnectFunction\n";
- }
- static std::mutex clientMutex;
- static Server::FullServerClientConnectFunction onFullServerClientConnect = defaultFullServerClientConnect;
- static Server::ClientConnectFunction onClientConnect = defaultClientConnect;
- static Server::ClientPackageFunction onClientPackage = defaultClientPackage;
- static Server::ClientDisconnectFunction onClientDisconnect = defaultClientDisconnect;
- void Server::setFullServerClientConnectFunction(Server::FullServerClientConnectFunction f) {
- onFullServerClientConnect = f;
- }
- void Server::setClientConnectFunction(Server::ClientConnectFunction f) {
- onClientConnect = f;
- }
- void Server::setClientPackageFunction(Server::ClientPackageFunction f) {
- onClientPackage = f;
- }
- void Server::setClientDisconnectFunction(Server::ClientDisconnectFunction f) {
- onClientDisconnect = f;
- }
- static void listenOnClient(ConnectedClient& cc) {
- // poll data
- struct pollfd fds;
- fds.fd = cc.socket; // file descriptor for polling
- fds.events = POLLIN; // wait until data is ready to read
- fds.revents = 0; // return events - none
- //onClientConnect(cc.socket);
- Stream st;
- while(server.shouldRun) {
- // 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) {
- st.readSocket(cc.socket);
- if(st.hasData()) {
- onClientPackage(cc.socket, st);
- } else {
- // client closed connection
- break;
- }
- } else if(pollData == -1) {
- printError("cannot poll from client");
- break;
- }
- }
- onClientDisconnect(cc.socket);
- // reset slot for another client
- if(server.shouldRun) {
- std::lock_guard<std::mutex> lg(clientMutex);
- if(close(cc.socket) == -1) {
- printError("cannot close socket of client");
- }
- cc.socket = -1;
- clientAmount--;
- }
- }
- static bool addClient(int clientSocket) {
- std::lock_guard<std::mutex> lg(clientMutex);
- if(clientAmount >= maxClients) {
- onFullServerClientConnect(clientSocket);
- return true;
- } else {
- // search for free slot
- uint16_t index = 0;
- while(index < maxClients) {
- if(server.clients[index].socket == -1) {
- break;
- }
- index++;
- }
- if(index >= maxClients) {
- std::cout << "cannot find free slot - even if there should be one\n";
- return true;
- }
- //ensure old thread has ended
- if(!server.clients[index].th.joinable()) {
- std::cout << "cannot join thread of non used client connection\n";
- return true;
- }
- server.clients[index].th.join();
- server.clients[index].socket = clientSocket;
- server.clients[index].th = std::thread(listenOnClient, std::ref(server.clients[index]));
- clientAmount++;
- return false;
- }
- }*/
|