From f652ba1f348f0a88243be5a7ada44bf919bffcb8 Mon Sep 17 00:00:00 2001 From: Brad Arant Date: Sat, 7 Nov 2020 17:28:24 -0800 Subject: [PATCH] Added vscode --- .vscode/c_cpp_properties.json | 29 +++++++++ EPoll.cpp | 76 +++++++++++----------- IPAddressList.h | 8 +-- TCPSession.cpp | 58 +++++++++-------- TCPSession.h | 119 ++++++++++++++++------------------ compile | 11 ++-- 6 files changed, 165 insertions(+), 136 deletions(-) create mode 100644 .vscode/c_cpp_properties.json diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json new file mode 100644 index 0000000..a426fd3 --- /dev/null +++ b/.vscode/c_cpp_properties.json @@ -0,0 +1,29 @@ +{ + "configurations": [ + { + "name": "Linux", + "includePath": [ + "${workspaceFolder}/**" + ], + "defines": [], + "compilerPath": "/usr/bin/gcc", + "cStandard": "gnu17", + "cppStandard": "gnu++14", + "intelliSenseMode": "gcc-x64", + "compileCommands": "./compile" + }, + { + "name": "config", + "includePath": [ + "${workspaceFolder}/**" + ], + "defines": [], + "compilerPath": "/usr/bin/gcc", + "cStandard": "gnu17", + "cppStandard": "gnu++17", + "intelliSenseMode": "gcc-x64", + "compileCommands": "./compile" + } + ], + "version": 4 +} \ No newline at end of file diff --git a/EPoll.cpp b/EPoll.cpp index 9b4f0c9..2ec4d47 100644 --- a/EPoll.cpp +++ b/EPoll.cpp @@ -4,96 +4,96 @@ #include "Exception.h" namespace core { - + EPoll::EPoll() : Command() { - + coreutils::Log(coreutils::LOG_DEBUG_2) << "EPoll object being constructed."; - + maxSockets = 1000; - epfd = epoll_create1(0); - terminateThreads = false; + epfd = epoll_create1(0); + terminateThreads = false; } - + EPoll::~EPoll() { coreutils::Log(coreutils::LOG_DEBUG_2) << "BMAEPoll destructed."; } - + bool EPoll::start(int numberOfThreads, int maxSockets) { - + coreutils::Log(coreutils::LOG_DEBUG_2) << "Starting epoll event processing."; - + this->numberOfThreads = numberOfThreads; - + coreutils::Log(coreutils::LOG_DEBUG_3) << "Number of threads starting is " << numberOfThreads << "."; coreutils::Log(coreutils::LOG_DEBUG_3) << "Maximum connections is " << maxSockets << "."; - + // TODO: Set the number of maximum open files to the maxSockets value. - // + // //---------------------------------------------------------------------- // Create thread objects into vector for number of threads requested. // Hand all the threads a pointer to the EPoll object so they can run // the socket handlers. //---------------------------------------------------------------------- - - for(int ix = 0; ix < numberOfThreads; ++ix) + + for(int ix = 0; ix < numberOfThreads; ++ix) threads.emplace_back(*this); - + for(int ix = 0; ix < numberOfThreads; ++ix) threads[ix].start(); - - return true; + + return true; } - + bool EPoll::stop() { - + terminateThreads = true; - + //-------------------------------------------------------- // Kill and join all the threads that have been started. //-------------------------------------------------------- - + for(int ix = 0; ix < numberOfThreads; ++ix) threads[ix].join(); - + //-------------------------- // Close the epoll socket. //-------------------------- - + close(epfd); - - return true; + + return true; } - + bool EPoll::isStopping() { return terminateThreads; } - + bool EPoll::registerSocket(Socket *socket) { coreutils::Log(coreutils::LOG_DEBUG_3) << "Registering socket " << socket->getDescriptor() << "."; enableSocket(socket); return true; } - + bool EPoll::unregisterSocket(Socket *socket) { coreutils::Log(coreutils::LOG_DEBUG_3) << "Unregistering socket " << socket->getDescriptor() << "."; disableSocket(socket); - return true; + return true; } - + int EPoll::getDescriptor() { return epfd; } - + int EPoll::processCommand(std::string command, TCPSession *session, std::stringstream &data) { - int sequence = 0; + int sequence = 0; for(auto threadx : threads) { data << "|" << ++sequence; - threadx.output(data); + threadx.output(data); data << "|" << std::endl; - } + } return 1; } - + void EPoll::enableSocket(Socket *socket) { coreutils::Log(coreutils::LOG_DEBUG_4) << "Enabling socket " << socket->getDescriptor() << " for events."; struct epoll_event event; @@ -101,13 +101,13 @@ namespace core { event.events = EPOLLIN | EPOLLONESHOT | EPOLLRDHUP | EPOLLET; epoll_ctl(epfd, EPOLL_CTL_ADD, socket->getDescriptor(), &event); } - + void EPoll::disableSocket(Socket *socket) { coreutils::Log(coreutils::LOG_DEBUG_4) << "Disabling socket " << socket->getDescriptor() << " from events."; epoll_ctl(epfd, EPOLL_CTL_DEL, socket->getDescriptor(), NULL); } - - void EPoll::resetSocket(Socket *socket) { + + void EPoll::resetSocket(Socket *socket) { coreutils::Log(coreutils::LOG_DEBUG_4) << "Resetting socket " << socket->getDescriptor() << " for read."; struct epoll_event event; event.data.ptr = socket; diff --git a/IPAddressList.h b/IPAddressList.h index 0dac766..0a5c27c 100644 --- a/IPAddressList.h +++ b/IPAddressList.h @@ -10,17 +10,17 @@ namespace core { public: IPAddressList(); - + std::map getList(); void add(IPAddress ipAddress); bool remove(IPAddress ipAddress); bool contains(std::string ipAddress); - + private: std::map list; - std::map::iterator it = list.begin(); + std::map::iterator it = list.begin(); }; - + } #endif diff --git a/TCPSession.cpp b/TCPSession.cpp index 6239251..b122ac9 100644 --- a/TCPSession.cpp +++ b/TCPSession.cpp @@ -4,23 +4,23 @@ #include "PString.h" namespace core { - + TCPSession::TCPSession(EPoll &ePoll, TCPServer &server, std::string text) : TCPSocket(ePoll, text), server(server) {} - + TCPSession::~TCPSession() { server.removeFromSessionList(this); } - + void TCPSession::output(std::stringstream &data) { data << "|" << ipAddress.getClientAddressAndPort(); } - + void TCPSession::protocol(std::string data = "") { - if(!server.commands.processRequest(data, this, out)) + if(!server.commands.processRequest(data, this, out)) if(data != "") server.sessionErrorHandler("Invalid data received.", out); } - + void TCPSession::onRegistered() { onConnected(); protocol(); @@ -30,17 +30,17 @@ namespace core { } void TCPSession::onConnected() {} - + void TCPSession::onDataReceived(char *data, int len) { if(len > 0) { lineBuffer = (char *)realloc(lineBuffer, lineBufferSize + len); memcpy(lineBuffer + lineBufferSize, data, len); lineBufferSize += len; - while(lineBufferSize > 0) { + while(lineBufferSize > 0) { switch(mode) { case LINE: lineLength = strcspn(lineBuffer, "\r\n"); - if(lineLength == lineBufferSize) + if(lineLength == lineBufferSize) break; onLineReceived(std::string(lineBuffer, lineLength)); if(lineBuffer[lineLength] == '\r') @@ -48,53 +48,59 @@ namespace core { if(lineBuffer[lineLength] == '\n') ++lineLength; lineBufferSize -= lineLength; - if(lineBufferSize > 0) + if(lineBufferSize > 0) memmove(lineBuffer, lineBuffer + lineLength, lineBufferSize); - lineBuffer = (char *)realloc(lineBuffer, lineBufferSize); - break; + lineBuffer = (char *)realloc(lineBuffer, lineBufferSize); + break; case BLOCK: - if(lineBufferSize >= blockLength) { + if(lineBufferSize >= blockLength) { onBlockReceived(std::string(lineBuffer, blockLength)); lineBufferSize -= blockLength; - if(lineBufferSize > 0) + if(lineBufferSize > 0) memmove(lineBuffer, lineBuffer + blockLength, lineBufferSize); - lineBuffer = (char *)realloc(lineBuffer, lineBufferSize); + lineBuffer = (char *)realloc(lineBuffer, lineBufferSize); } break; } } - } + } } void TCPSession::setMode(core::Mode mode, int blockSize) { this->mode = mode; this->blockSize = blockSize; } - + void TCPSession::onLineReceived(std::string line) { coreutils::Log(coreutils::LOG_DEBUG_3) << "[" << line << "]"; protocol(line); send(); if(term) - shutdown("termination requested"); + shutdown("termination requested"); } - + + void TCPSession::onBlockReceived(std::string block) { + coreutils::Log(coreutils::LOG_DEBUG_3) << "[" << block.length() << "]"; + if(term) + shutdown("termination requested"); + } + void TCPSession::sendToAll() { - for(auto session : server.sessions) + for(auto session : server.sessions) if(session != this) - session->write(out.str()); + session->write(out.str()); out.str(""); } - + void TCPSession::sendToAll(SessionFilter filter) { - for(auto session : server.sessions) - if(filter.test(*session)) + for(auto session : server.sessions) + if(filter.test(*session)) if(session != this) session->write(out.str()); out.str(""); } - + void TCPSession::send() { if(out.tellp() > 0) write(out.str()); @@ -104,5 +110,5 @@ namespace core { void TCPSession::terminate() { term = true; } - + } diff --git a/TCPSession.h b/TCPSession.h index 00c63ca..aa3c0d2 100644 --- a/TCPSession.h +++ b/TCPSession.h @@ -8,151 +8,144 @@ namespace core { class Command; enum Mode {LINE, BLOCK}; - + class TCPServer; - + /// /// TCPSession /// /// TCPSession defines the nature of the interaction with the client /// and stores persistent data for a defined session. TCPSession objects - /// are not sockets but instead provide a communications control + /// are not sockets but instead provide a communications control /// mechanism. Protocol conversations are provided through extensions - /// from this object. - /// - /// + /// from this object. /// - + /// + /// + class TCPSession : public TCPSocket { - + public: /// /// /// - + TCPSession(EPoll &ePoll, TCPServer &server, std::string text = ""); /// /// /// - - ~TCPSession(); - + + ~TCPSession(); + Command *grab = NULL; - + virtual void output(std::stringstream &data); /// /// Use out to send data to the session socket or other session sockets. /// - + std::stringstream out; - - /// + + /// /// The send method is used to output the contents of the out stream /// to the session containing the stream. /// - + void send(); - + /// /// Use this sendToAll method to output the contents of the out stream - /// to all the connections on the server excluding the sender session. + /// to all the connections on the server excluding the sender session. /// - + void sendToAll(); - + /// /// Use this sendToAll method to output the contents of the out stream /// to all the connections on the server excluding the sender session /// and the entries identified by the passed in filter object. /// - + void sendToAll(SessionFilter filter); /// - /// Use this method to terminate this TCPSession. + /// Use this method to terminate this TCPSession. /// - + void terminate(); - + /// - /// /// - + /// + TCPServer &server; - /// - /// Set this value to control the next read event coming - /// from this socket. - /// - -// enum Mode {LINE, BLOCK}; - protected: - + /// /// /// - virtual void onRegistered() override; + virtual void onRegistered() override; /// /// Override this method to receive data directly from the socket as data is /// received. If you need data split by line termination characters then /// override the onLineReceived method instead. /// - - virtual void onDataReceived(char *data, int len) override; - + + virtual void onDataReceived(char *data, int len) override; + /// - /// Override the onLineReceived method to receive a string of characters that - /// represents a single line of data terminated by a LF or CRLF. If onDataReceived + /// Override the onLineReceived method to receive a string of characters that + /// represents a single line of data terminated by a LF or CRLF. If onDataReceived /// was overriden this method will not be called unless the onDataReceived calls /// this method explicitly using the class and member name. /// - - virtual void onLineReceived(std::string line); - + + virtual void onLineReceived(std::string line); + /// - /// Override the onBlockReceived method to receive a string of characters that - /// represents a single block of data of length determined by the block length value. If - /// onDataReceived was overriden this method will not be called unless the onDataReceived + /// Override the onBlockReceived method to receive a string of characters that + /// represents a single block of data of length determined by the block length value. If + /// onDataReceived was overriden this method will not be called unless the onDataReceived /// calls this method explicitly using the class and member name. /// - - virtual void onBlockReceived(std::string block); + + virtual void onBlockReceived(std::string block); /// /// This method is called from within the protocol method when protocol is called /// on the initial connection where the data is an empty string. Use this method /// to deliver a message to the connection upon connection. /// - + virtual void onConnected(); - + /// /// Override the protocol method to manage and control the session communications /// in your inherited session. If you do not override this method then the Session - /// default will process the 'commands' added to the server object using the - /// processRequest method on the session input. + /// default will process the 'commands' added to the server object using the + /// processRequest method on the session input. /// - /// When data is received within the session two modes are available to pass the + /// When data is received within the session two modes are available to pass the /// data through the protocol method: LINE or BLOCK. /// - - virtual void protocol(std::string data); + + virtual void protocol(std::string data); /// - /// Use the setMode method to set the receiving mode for the data on this socket. - /// Data can be received in LINE mode, which will receive data from the socket one + /// Use the setMode method to set the receiving mode for the data on this socket. + /// Data can be received in LINE mode, which will receive data from the socket one /// line at a time, or BLOCK mode where a certain specified data block is received /// before calling the onBlockReceived method. /// - - void setMode(core::Mode mode, int size = 0); - + + void setMode(core::Mode mode, int size = 0); + private: char *lineBuffer = NULL; int lineBufferSize = 0; @@ -162,9 +155,9 @@ namespace core { bool term = false; core::Mode mode = LINE; int blockSize; - + }; - + } #endif diff --git a/compile b/compile index 6032a60..a07a0ec 100755 --- a/compile +++ b/compile @@ -3,17 +3,17 @@ for file in *.cpp do filename="${file%.*}" - list="$list $filename.o" + list="$list $filename.o" echo -n "Compiling $filename..." - g++ -g -c -I../CoreUtils $file + g++ -g -c -I../CoreUtils $file if [ $? = '0' ] then echo "OK" else echo "ERROR" exit -1 - fi - + fi + done wait @@ -25,8 +25,9 @@ then else echo "ERROR" exit -1 -fi +fi echo -n "Building library documentation manual..." doxygen docs/latex/doxygen.sty >/dev/null 2>/dev/null echo "OK" +