Added vscode
This commit is contained in:
parent
177bc602af
commit
f652ba1f34
29
.vscode/c_cpp_properties.json
vendored
Normal file
29
.vscode/c_cpp_properties.json
vendored
Normal file
@ -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
|
||||
}
|
76
EPoll.cpp
76
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;
|
||||
|
@ -10,17 +10,17 @@ namespace core {
|
||||
|
||||
public:
|
||||
IPAddressList();
|
||||
|
||||
|
||||
std::map<std::string, IPAddress> getList();
|
||||
void add(IPAddress ipAddress);
|
||||
bool remove(IPAddress ipAddress);
|
||||
bool contains(std::string ipAddress);
|
||||
|
||||
|
||||
private:
|
||||
std::map<std::string, IPAddress> list;
|
||||
std::map<std::string, IPAddress>::iterator it = list.begin();
|
||||
std::map<std::string, IPAddress>::iterator it = list.begin();
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
119
TCPSession.h
119
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
|
||||
|
11
compile
11
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"
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user