Fix linux build.
This commit is contained in:
parent
a6d92e142f
commit
9e1d951520
50 changed files with 1586 additions and 1192 deletions
|
@ -3,6 +3,8 @@ set(MODULE_NAME geometry)
|
|||
list(APPEND HEADERS
|
||||
AbstractGeometricItem.h
|
||||
Bounds.h
|
||||
Transform.h
|
||||
Rotation.h
|
||||
grid/AbstractGrid.h
|
||||
grid/TypedGrid.h
|
||||
grid/Grid.h
|
||||
|
@ -30,6 +32,7 @@ list(APPEND HEADERS
|
|||
)
|
||||
|
||||
list(APPEND SOURCES
|
||||
Rotation.cpp
|
||||
Transform.cpp
|
||||
grid/AbstractGrid.cpp
|
||||
math/Linalg.cpp
|
||||
|
|
31
src/base/geometry/Rotation.cpp
Normal file
31
src/base/geometry/Rotation.cpp
Normal file
|
@ -0,0 +1,31 @@
|
|||
#include "Rotation.h"
|
||||
|
||||
Rotation::Rotation(double angle, Axis axis, const Point& loc, const Vector& customAxis)
|
||||
: mAngle(angle),
|
||||
mAxis(axis),
|
||||
mPoint(loc),
|
||||
mCustomAxis(customAxis),
|
||||
mMatrix(3, 3)
|
||||
{
|
||||
updateMatrix();
|
||||
}
|
||||
|
||||
const Matrix& Rotation::getMatrix() const
|
||||
{
|
||||
return mMatrix;
|
||||
}
|
||||
|
||||
bool Rotation::isIdentity() const
|
||||
{
|
||||
return mMatrix.isIdentity();
|
||||
}
|
||||
|
||||
bool Rotation::isEqual(const Rotation& rotation) const
|
||||
{
|
||||
return mMatrix == rotation.mMatrix;
|
||||
}
|
||||
|
||||
void Rotation::updateMatrix()
|
||||
{
|
||||
|
||||
}
|
45
src/base/geometry/Rotation.h
Normal file
45
src/base/geometry/Rotation.h
Normal file
|
@ -0,0 +1,45 @@
|
|||
#pragma once
|
||||
|
||||
#include "Point.h"
|
||||
#include "Vector.h"
|
||||
#include "Matrix.h"
|
||||
|
||||
class Rotation
|
||||
{
|
||||
public:
|
||||
enum class Axis
|
||||
{
|
||||
X,
|
||||
Y,
|
||||
Z,
|
||||
USER
|
||||
};
|
||||
|
||||
Rotation(double angle = 0.0, Axis axis = Axis::Z, const Point& loc = {}, const Vector& customAxis = {});
|
||||
|
||||
const Matrix& getMatrix() const;
|
||||
|
||||
bool isIdentity() const;
|
||||
|
||||
bool isEqual(const Rotation& rotation) const;
|
||||
|
||||
bool operator==(const Rotation& rhs) const
|
||||
{
|
||||
return isEqual(rhs);
|
||||
}
|
||||
|
||||
bool operator!=(const Rotation& rhs) const
|
||||
{
|
||||
return !operator==(rhs);
|
||||
}
|
||||
|
||||
private:
|
||||
void updateMatrix();
|
||||
|
||||
double mAngle{ 0 };
|
||||
Axis mAxis{ Axis::Z };
|
||||
Point mPoint;
|
||||
Vector mCustomAxis;
|
||||
|
||||
Matrix mMatrix;
|
||||
};
|
|
@ -1,43 +1,92 @@
|
|||
#include "Transform.h"
|
||||
|
||||
Transform::Transform(const Point& location, double scaleX, double scaleY, double scaleZ)
|
||||
: mLocation(location),
|
||||
mScaleX(scaleX),
|
||||
mScaleY(scaleY),
|
||||
mScaleZ(scaleZ)
|
||||
Scale::Scale(double x, double y, double z)
|
||||
: mX(x),
|
||||
mY(y),
|
||||
mZ(z)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool Scale::isIdentity() const
|
||||
{
|
||||
return mX == 1.0 && mY == 1.0 && mZ == 1.0;
|
||||
}
|
||||
|
||||
bool Scale::isEqual(const Scale& scale) const
|
||||
{
|
||||
return mX == scale.mX && mY == scale.mY && mZ == scale.mZ;
|
||||
}
|
||||
|
||||
Transform::Transform(const Point& location, const Scale& scale, const Rotation& rotation)
|
||||
: mLocation(location),
|
||||
mScale(scale),
|
||||
mRotation(rotation),
|
||||
mMatrix(4, 4)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Transform::applyPre(const Transform& transform)
|
||||
{
|
||||
mLocation.move(transform.getLocation().getX(), transform.getLocation().getY(), transform.getLocation().getZ());
|
||||
mScale *= transform.getScale();
|
||||
}
|
||||
|
||||
const Point& Transform::getLocation() const
|
||||
{
|
||||
return mLocation;
|
||||
}
|
||||
|
||||
double Transform::getScaleX() const
|
||||
const Scale& Transform::getScale() const
|
||||
{
|
||||
return mScaleX;
|
||||
return mScale;
|
||||
}
|
||||
|
||||
double Transform::getScaleY() const
|
||||
const Rotation& Transform::getRotation() const
|
||||
{
|
||||
return mScaleY;
|
||||
return mRotation;
|
||||
}
|
||||
|
||||
double Transform::getScaleZ() const
|
||||
bool Transform::isEqual(const Transform& transform) const
|
||||
{
|
||||
return mScaleZ;
|
||||
return (mLocation == transform.mLocation) && (mScale == transform.mScale) && (mRotation == transform.mRotation);
|
||||
}
|
||||
|
||||
bool Transform::isIdentityTransform() const
|
||||
{
|
||||
return mLocation.isAtOrigin() && mScale.isIdentity();
|
||||
}
|
||||
|
||||
void Transform::setLocation(const Point& loc)
|
||||
{
|
||||
mLocation = loc;
|
||||
if (mLocation != loc)
|
||||
{
|
||||
mLocation = loc;
|
||||
updateMatrix();
|
||||
}
|
||||
}
|
||||
|
||||
void Transform::setScale(double scaleX, double scaleY, double scaleZ)
|
||||
void Transform::setScale(const Scale& scale)
|
||||
{
|
||||
mScaleX = scaleX;
|
||||
mScaleY = scaleY;
|
||||
mScaleZ = scaleZ;
|
||||
if (mScale != scale)
|
||||
{
|
||||
mScale = scale;
|
||||
updateMatrix();
|
||||
}
|
||||
}
|
||||
|
||||
void Transform::setRotation(const Rotation& rotation)
|
||||
{
|
||||
if (mRotation != rotation)
|
||||
{
|
||||
mRotation = rotation;
|
||||
updateMatrix();
|
||||
}
|
||||
}
|
||||
|
||||
void Transform::updateMatrix()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,68 +1,65 @@
|
|||
#pragma once
|
||||
|
||||
#include "Point.h"
|
||||
#include "Vector.h"
|
||||
|
||||
class Rotation
|
||||
{
|
||||
public:
|
||||
enum class Axis
|
||||
{
|
||||
X,
|
||||
Y,
|
||||
Z,
|
||||
USER
|
||||
};
|
||||
|
||||
|
||||
Rotation(double angle = 0.0, Axis axis = Axis::Z, const Point& loc = {}, const Vector& customAxis = {})
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private:
|
||||
double mAngle{ 0 };
|
||||
Axis mAxis{ Axis::Z };
|
||||
Point mPoint;
|
||||
Vector mCustomAxis;
|
||||
};
|
||||
#include "Rotation.h"
|
||||
|
||||
struct Scale
|
||||
{
|
||||
Scale(double x = 1.0, double y = 1.0, double z = 1.0);
|
||||
|
||||
bool isIdentity() const;
|
||||
|
||||
bool isEqual(const Scale& scale) const;
|
||||
|
||||
void operator*=(const Scale& rhs)
|
||||
{
|
||||
mX *= rhs.mX;
|
||||
mY *= rhs.mY;
|
||||
mZ *= rhs.mZ;
|
||||
}
|
||||
|
||||
bool operator==(const Scale& rhs) const
|
||||
{
|
||||
return isEqual(rhs);
|
||||
}
|
||||
|
||||
bool operator!=(const Scale& rhs) const
|
||||
{
|
||||
return !operator==(rhs);
|
||||
}
|
||||
|
||||
double mX{1.0};
|
||||
double mY{1.0};
|
||||
double mZ{1.0};
|
||||
};
|
||||
|
||||
class Transform
|
||||
{
|
||||
public:
|
||||
Transform(const Point& location = {}, double scaleX = 1.0, double scaleY = 1.0, double scaleZ = 1.0);
|
||||
Transform(const Point& location = {}, const Scale& scale = {}, const Rotation& rotation = {});
|
||||
|
||||
void applyPre(const Transform& transform)
|
||||
{
|
||||
mLocation.move(transform.getLocation().getX(), transform.getLocation().getY(), transform.getLocation().getZ());
|
||||
mScaleX *= transform.getScaleX();
|
||||
mScaleY *= transform.getScaleY();
|
||||
mScaleZ *= transform.getScaleZ();
|
||||
}
|
||||
|
||||
void setLocation(const Point& loc);
|
||||
|
||||
void setScale(double scaleX, double scaleY = 1.0, double scaleZ = 1.0);
|
||||
void applyPre(const Transform& transform);
|
||||
|
||||
const Point& getLocation() const;
|
||||
|
||||
double getScaleX() const;
|
||||
const Scale& getScale() const;
|
||||
|
||||
double getScaleY() const;
|
||||
const Rotation& getRotation() const;
|
||||
|
||||
double getScaleZ() const;
|
||||
const Matrix& getMatrix() const;
|
||||
|
||||
bool isEqual(const Transform& transform) const;
|
||||
|
||||
bool isIdentityTransform() const;
|
||||
|
||||
void setLocation(const Point& loc);
|
||||
|
||||
void setScale(const Scale& scale);
|
||||
|
||||
void setRotation(const Rotation& rotation);
|
||||
|
||||
bool operator==(const Transform& rhs) const
|
||||
{
|
||||
return (mLocation == rhs.mLocation)
|
||||
&& (mScaleX == rhs.mScaleX)
|
||||
&& (mScaleY == rhs.mScaleY)
|
||||
&& (mScaleZ == rhs.mScaleZ);
|
||||
return isEqual(rhs);
|
||||
}
|
||||
|
||||
bool operator!=(const Transform& rhs) const
|
||||
|
@ -70,24 +67,11 @@ public:
|
|||
return !operator==(rhs);
|
||||
}
|
||||
|
||||
bool hasDefaultLocation() const
|
||||
{
|
||||
return mLocation.getX() == 0.0 && mLocation.getY() == 0.0 && mLocation.getZ() == 0.0;
|
||||
}
|
||||
|
||||
bool hasDefaultScale() const
|
||||
{
|
||||
return mScaleX == 1.0 && mScaleY == 1.0 && mScaleZ == 1.0;
|
||||
}
|
||||
|
||||
bool isDefaultTransform() const
|
||||
{
|
||||
return hasDefaultLocation() && hasDefaultScale();
|
||||
}
|
||||
|
||||
private:
|
||||
void updateMatrix();
|
||||
|
||||
Point mLocation;
|
||||
double mScaleX{1};
|
||||
double mScaleY{1};
|
||||
double mScaleZ{1};
|
||||
Scale mScale;
|
||||
Rotation mRotation;
|
||||
Matrix mMatrix;
|
||||
};
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
#include "Matrix.h"
|
||||
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
|
||||
Matrix::Matrix(std::size_t numRows, std::size_t numColumns)
|
||||
: mNumRows(numRows),
|
||||
mNumColumns(numColumns)
|
||||
{
|
||||
mData = std::vector<double>(numRows * numColumns, 0.0);
|
||||
}
|
||||
|
||||
bool Matrix::isIdentity() const
|
||||
{
|
||||
if (!isSquare())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for(std::size_t idx=0; idx<mNumRows; idx++)
|
||||
{
|
||||
for(std::size_t jdx=0; jdx<mNumColumns; jdx++)
|
||||
{
|
||||
if (idx == jdx)
|
||||
{
|
||||
if (getItem(idx, jdx) != 1.0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (getItem(idx, jdx) != 0.0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
double Matrix::getItem(std::size_t rowId, std::size_t columnId) const
|
||||
{
|
||||
const auto index = getFlatIndex(rowId, columnId);
|
||||
if (index >= mData.size())
|
||||
{
|
||||
throw std::range_error("Out of bounds array access: " + std::to_string(index) + " for size " + std::to_string(mData.size()));
|
||||
}
|
||||
return mData[getFlatIndex(rowId, columnId)];
|
||||
}
|
||||
|
||||
bool Matrix::isSquare() const
|
||||
{
|
||||
return mNumRows == mNumColumns;
|
||||
}
|
||||
|
||||
bool Matrix::isEqual(const Matrix& matrix) const
|
||||
{
|
||||
return mData == matrix.mData;
|
||||
}
|
||||
|
||||
std::size_t Matrix::getFlatIndex(std::size_t rowId, std::size_t columnId) const
|
||||
{
|
||||
return columnId + rowId*mNumColumns;
|
||||
}
|
|
@ -5,10 +5,30 @@
|
|||
class Matrix
|
||||
{
|
||||
public:
|
||||
Matrix(unsigned numRows, unsigned numColumns)
|
||||
{
|
||||
mData = std::vector<double>(numRows * numColumns, 0.0);
|
||||
}
|
||||
Matrix(std::size_t numRows, std::size_t numColumns);
|
||||
|
||||
std::size_t getFlatIndex(std::size_t rowId, std::size_t columnId) const;
|
||||
|
||||
double getItem(std::size_t rowId, std::size_t columnId) const;
|
||||
|
||||
bool isIdentity() const;
|
||||
|
||||
bool isSquare() const;
|
||||
|
||||
bool isEqual(const Matrix& matrix) const;
|
||||
|
||||
bool operator==(const Matrix& rhs) const
|
||||
{
|
||||
return isEqual(rhs);
|
||||
}
|
||||
|
||||
bool operator!=(const Matrix& rhs) const
|
||||
{
|
||||
return !operator==(rhs);
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<double> mData;
|
||||
};
|
||||
std::size_t mNumRows{0};
|
||||
std::size_t mNumColumns{0};
|
||||
std::vector<double> mData;
|
||||
};
|
||||
|
|
|
@ -79,15 +79,20 @@ double Point::getDeltaZ(const Point& point) const
|
|||
return point.getZ() - mZ;
|
||||
}
|
||||
|
||||
bool Point::isAtOrigin() const
|
||||
{
|
||||
return mX == 0.0 && mY == 0.0 && mZ == 0.0;
|
||||
}
|
||||
|
||||
void Point::apply(const Transform& transform)
|
||||
{
|
||||
mX -= transform.getLocation().getX();
|
||||
mY -= transform.getLocation().getY();
|
||||
mZ -= transform.getLocation().getZ();
|
||||
|
||||
mX *= transform.getScaleX();
|
||||
mY *= transform.getScaleY();
|
||||
mZ *= transform.getScaleZ();
|
||||
mX *= transform.getScale().mX;
|
||||
mY *= transform.getScale().mY;
|
||||
mZ *= transform.getScale().mZ;
|
||||
}
|
||||
|
||||
void Point::move(double x, double y, double z)
|
||||
|
|
|
@ -22,6 +22,8 @@ public:
|
|||
|
||||
void apply(const Transform& transform);
|
||||
|
||||
bool isAtOrigin() const;
|
||||
|
||||
void move(double x, double y, double z = 0);
|
||||
|
||||
double getX() const;
|
||||
|
|
|
@ -7,10 +7,8 @@ if(UNIX)
|
|||
list(APPEND platform_INCLUDES
|
||||
sockets/BerkeleySocket.h
|
||||
sockets/BerkeleySocket.cpp
|
||||
sockets/UnixSocketInterface.h
|
||||
sockets/UnixSocketInterface.cpp
|
||||
server/UnixSockerServer.h
|
||||
server/UnixSockerServer.cpp
|
||||
server/UnixSocketServer.h
|
||||
server/UnixSocketServer.cpp
|
||||
client/unix/UnixSocketClient.h
|
||||
client/unix/UnixSocketClient.cpp
|
||||
)
|
||||
|
@ -45,7 +43,6 @@ list(APPEND HEADERS
|
|||
server/HttpServer.h
|
||||
server/PlatformSocketServer.h
|
||||
sockets/Socket.h
|
||||
sockets/SocketInterface.h
|
||||
sockets/IPlatformSocket.h
|
||||
)
|
||||
|
||||
|
@ -70,4 +67,4 @@ target_include_directories(${MODULE_NAME} PUBLIC
|
|||
set_target_properties( ${MODULE_NAME} PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON )
|
||||
target_link_libraries( ${MODULE_NAME} PUBLIC core ${platform_LIBS})
|
||||
|
||||
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER src/base)
|
||||
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER src/base)
|
||||
|
|
|
@ -11,38 +11,38 @@
|
|||
HttpClient::HttpClient()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
mSocketClient = std::make_unique<WinsockClient>();
|
||||
mSocketClient = std::make_unique<WinsockClient>();
|
||||
#else
|
||||
mSocketClient = std::make_unique<UnixSocketClient>();
|
||||
mSocketClient = std::make_unique<UnixSocketClient>();
|
||||
#endif
|
||||
}
|
||||
|
||||
HttpResponse HttpClient::makeRequest(const HttpRequest& request, const Address& address)
|
||||
{
|
||||
PlatformSocketClient::Address socket_address;
|
||||
socket_address.mHost = address.mHost;
|
||||
socket_address.mPort = address.mPort;
|
||||
socket_address.mPrefix = address.mPrefix;
|
||||
PlatformSocketClient::Address socket_address;
|
||||
socket_address.mHost = address.mHost;
|
||||
socket_address.mPort = address.mPort;
|
||||
socket_address.mPrefix = address.mPrefix;
|
||||
|
||||
const auto message = request.toString(address.mHost);
|
||||
const auto message = request.toString(address.mHost);
|
||||
|
||||
MLOG_INFO("Output http request: " << message);
|
||||
MLOG_INFO("Output http request: " << message);
|
||||
|
||||
auto socket_response = mSocketClient->request(socket_address, message);
|
||||
auto socket_response = mSocketClient->request(socket_address, message);
|
||||
|
||||
HttpResponse response;
|
||||
if (socket_response.mStatus == PlatformSocketClient::Result::Status::OK)
|
||||
{
|
||||
response.fromMessage(socket_response.mBody);
|
||||
}
|
||||
else
|
||||
{
|
||||
MLOG_ERROR("Http request client error: " << socket_response.mErrorMessage << " | with code: " << socket_response.mErrorCode);
|
||||
HttpResponse response;
|
||||
if (socket_response.mStatus == PlatformSocketClient::Result::Status::OK)
|
||||
{
|
||||
response.fromMessage(socket_response.mBody);
|
||||
}
|
||||
else
|
||||
{
|
||||
MLOG_ERROR("Http request client error: " << socket_response.mErrorMessage << " | with code: " << socket_response.mErrorCode);
|
||||
|
||||
HttpResponse::ClientError error;
|
||||
error.mMessage = socket_response.mErrorMessage;
|
||||
error.mCode = socket_response.mErrorCode;
|
||||
response.setClientError(error);
|
||||
}
|
||||
return response;
|
||||
}
|
||||
HttpResponse::ClientError error;
|
||||
error.mMessage = socket_response.mErrorMessage;
|
||||
error.mCode = socket_response.mErrorCode;
|
||||
response.setClientError(error);
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
|
|
@ -9,16 +9,16 @@
|
|||
class HttpClient
|
||||
{
|
||||
public:
|
||||
struct Address
|
||||
{
|
||||
std::string mPrefix;
|
||||
std::string mHost;
|
||||
unsigned int mPort{ 8000 };
|
||||
};
|
||||
struct Address
|
||||
{
|
||||
std::string mPrefix;
|
||||
std::string mHost;
|
||||
unsigned int mPort{ 8000 };
|
||||
};
|
||||
|
||||
HttpClient();
|
||||
HttpResponse makeRequest(const HttpRequest& request, const Address& address);
|
||||
HttpClient();
|
||||
HttpResponse makeRequest(const HttpRequest& request, const Address& address);
|
||||
|
||||
private:
|
||||
std::unique_ptr<PlatformSocketClient> mSocketClient;
|
||||
};
|
||||
std::unique_ptr<PlatformSocketClient> mSocketClient;
|
||||
};
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
#include "UnixSocketClient.h"
|
||||
|
||||
UnixSocketClient::UnixSocketClient()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
UnixSocketClient::~UnixSocketClient()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
UnixSocketClient::Result UnixSocketClient::request(const Address& address, const std::string& message)
|
||||
{
|
||||
UnixSocketClient::Result result;
|
||||
|
||||
auto socket = std::make_unique<BerkeleySocket>(address.mHost, address.mPort);
|
||||
auto response = socket->send(message);
|
||||
|
||||
if (socket->getState().mConnectStatus != Socket::State::ConnectStatus::FAILED)
|
||||
{
|
||||
result.mStatus = UnixSocketClient::Result::Status::OK;
|
||||
result.mBody = response;
|
||||
}
|
||||
else
|
||||
{
|
||||
result.mStatus = UnixSocketClient::Result::Status::FAILED;
|
||||
result.mErrorCode = socket->getState().mErrorCode;
|
||||
result.mErrorMessage = socket->getState().mErrorMessage;
|
||||
}
|
||||
return result;
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
#pragma once
|
||||
|
||||
#include "BerkeleySocket.h"
|
||||
|
||||
#include "PlatformSocketClient.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
class UnixSocketClient : public PlatformSocketClient
|
||||
{
|
||||
public:
|
||||
UnixSocketClient();
|
||||
|
||||
virtual ~UnixSocketClient();
|
||||
|
||||
Result request(const Address& address, const std::string& message);
|
||||
};
|
|
@ -1,28 +1,28 @@
|
|||
#include "WinsockClient.h"
|
||||
|
||||
WinsockClient::WinsockClient()
|
||||
: mSocketInterface(std::make_unique<WinsockInterface>())
|
||||
: mSocketInterface(std::make_unique<WinsockInterface>())
|
||||
{
|
||||
mSocketInterface->initializeWinsock();
|
||||
mSocketInterface->initializeWinsock();
|
||||
}
|
||||
|
||||
WinsockClient::Result WinsockClient::request(const Address& address, const std::string& message)
|
||||
{
|
||||
WinsockClient::Result result;
|
||||
WinsockClient::Result result;
|
||||
|
||||
auto socket = std::make_unique<WinsockSocket>(address.mHost, address.mPort);
|
||||
auto response = socket->send(message);
|
||||
auto socket = std::make_unique<WinsockSocket>(address.mHost, address.mPort);
|
||||
auto response = socket->send(message);
|
||||
|
||||
if (socket->getState().mConnectStatus != Socket::State::ConnectStatus::FAILED)
|
||||
{
|
||||
result.mStatus = WinsockClient::Result::Status::OK;
|
||||
result.mBody = response;
|
||||
}
|
||||
else
|
||||
{
|
||||
result.mStatus = WinsockClient::Result::Status::FAILED;
|
||||
result.mErrorCode = socket->getState().mErrorCode;
|
||||
result.mErrorMessage = socket->getState().mErrorMessage;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
if (socket->getState().mConnectStatus != Socket::State::ConnectStatus::FAILED)
|
||||
{
|
||||
result.mStatus = WinsockClient::Result::Status::OK;
|
||||
result.mBody = response;
|
||||
}
|
||||
else
|
||||
{
|
||||
result.mStatus = WinsockClient::Result::Status::FAILED;
|
||||
result.mErrorCode = socket->getState().mErrorCode;
|
||||
result.mErrorMessage = socket->getState().mErrorMessage;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -10,10 +10,10 @@
|
|||
class WinsockClient : public PlatformSocketClient
|
||||
{
|
||||
public:
|
||||
WinsockClient();
|
||||
WinsockClient();
|
||||
|
||||
Result request(const Address& address, const std::string& message);
|
||||
Result request(const Address& address, const std::string& message);
|
||||
|
||||
private:
|
||||
std::unique_ptr<WinsockInterface> mSocketInterface;
|
||||
};
|
||||
std::unique_ptr<WinsockInterface> mSocketInterface;
|
||||
};
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
#include "UnixSocketServer.h"
|
||||
|
||||
#include "BerkeleySocket.h"
|
||||
|
||||
#include "FileLogger.h"
|
||||
|
||||
#include <thread>
|
||||
|
||||
UnixSocketServer::~UnixSocketServer()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void UnixSocketServer::listen(const Address& address, onConnectionSuccessFunc connectionSuccessFunc, onConnectionFailedFunc connectionFailedFunc)
|
||||
{
|
||||
mConnectionCallback = connectionSuccessFunc;
|
||||
mFailedCallback = connectionFailedFunc;
|
||||
|
||||
auto server_socket = std::make_unique<BerkeleySocket>(address.mHost, address.mPort);
|
||||
|
||||
auto on_connection = [this](int handle)
|
||||
{
|
||||
auto socket = std::make_unique<BerkeleySocket>(handle);
|
||||
this->onConnection(std::move(socket));
|
||||
};
|
||||
server_socket->doListen(on_connection);
|
||||
|
||||
if (server_socket->getState().mBindStatus == Socket::State::BindStatus::FAILED)
|
||||
{
|
||||
UnixSocketServer::Result result;
|
||||
result.mStatus = UnixSocketServer::Result::Status::FAILED;
|
||||
result.mErrorCode = server_socket->getState().mErrorCode;
|
||||
result.mErrorMessage = server_socket->getState().mErrorMessage;
|
||||
mFailedCallback(result);
|
||||
}
|
||||
}
|
||||
|
||||
void UnixSocketServer::shutDown()
|
||||
{
|
||||
mThreads.removeMarked();
|
||||
mThreads.joinAndClearAll();
|
||||
}
|
||||
|
||||
void UnixSocketServer::onConnection(std::unique_ptr<BerkeleySocket> s)
|
||||
{
|
||||
// House-keeping first - clean up any finished threads
|
||||
MLOG_INFO("Before thread cleanup: " << mThreads.size());
|
||||
|
||||
mThreads.removeMarked();
|
||||
|
||||
MLOG_INFO("After thread cleanup: " << mThreads.size());
|
||||
|
||||
auto worker_func = [this](std::unique_ptr<BerkeleySocket> s)
|
||||
{
|
||||
MLOG_INFO("Spawned thread for new connection");
|
||||
|
||||
mConnectionCallback(s.get());
|
||||
|
||||
MLOG_INFO("Finished thread for new connection");
|
||||
this->onThreadComplete(std::this_thread::get_id());
|
||||
};
|
||||
|
||||
auto worker = std::make_unique<std::thread>(worker_func, std::move(s));
|
||||
mThreads.add(std::move(worker));
|
||||
};
|
||||
|
||||
void UnixSocketServer::onThreadComplete(std::thread::id id)
|
||||
{
|
||||
mThreads.markForRemoval(id);
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
#pragma once
|
||||
|
||||
#include "PlatformSocketServer.h"
|
||||
#include "ThreadCollection.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
class BerkeleySocket;
|
||||
|
||||
class UnixSocketServer : public PlatformSocketServer
|
||||
{
|
||||
public:
|
||||
virtual ~UnixSocketServer();
|
||||
|
||||
void listen(const Address& address, onConnectionSuccessFunc connectionSuccessFunc, onConnectionFailedFunc connectionFailedFunc) override;
|
||||
|
||||
void shutDown() override;
|
||||
|
||||
private:
|
||||
void onConnection(std::unique_ptr<BerkeleySocket> clientHandle);
|
||||
|
||||
void onThreadComplete(std::thread::id id);
|
||||
|
||||
ThreadCollection mThreads;
|
||||
onConnectionSuccessFunc mConnectionCallback;
|
||||
onConnectionFailedFunc mFailedCallback;
|
||||
};
|
|
@ -14,64 +14,64 @@ WinsockServer::~WinsockServer()
|
|||
|
||||
void WinsockServer::listen(const Address& address, onConnectionSuccessFunc connectionSuccessFunc, onConnectionFailedFunc connectionFailedFunc)
|
||||
{
|
||||
if (!mWinsockInterface)
|
||||
{
|
||||
mWinsockInterface = std::make_unique<WinsockInterface>();
|
||||
mWinsockInterface->initializeWinsock();
|
||||
}
|
||||
if (!mWinsockInterface)
|
||||
{
|
||||
mWinsockInterface = std::make_unique<WinsockInterface>();
|
||||
mWinsockInterface->initializeWinsock();
|
||||
}
|
||||
|
||||
mConnectionCallback = connectionSuccessFunc;
|
||||
mFailedCallback = connectionFailedFunc;
|
||||
mConnectionCallback = connectionSuccessFunc;
|
||||
mFailedCallback = connectionFailedFunc;
|
||||
|
||||
auto server_socket = std::make_unique<WinsockSocket>(address.mHost, address.mPort);
|
||||
auto server_socket = std::make_unique<WinsockSocket>(address.mHost, address.mPort);
|
||||
|
||||
auto on_connection = [this](SOCKET handle)
|
||||
{
|
||||
auto socket = std::make_unique<WinsockSocket>(handle);
|
||||
this->onConnection(std::move(socket));
|
||||
};
|
||||
server_socket->doListen(on_connection);
|
||||
auto on_connection = [this](SOCKET handle)
|
||||
{
|
||||
auto socket = std::make_unique<WinsockSocket>(handle);
|
||||
this->onConnection(std::move(socket));
|
||||
};
|
||||
server_socket->doListen(on_connection);
|
||||
|
||||
if (server_socket->getState().mBindStatus == Socket::State::BindStatus::FAILED)
|
||||
{
|
||||
WinsockServer::Result result;
|
||||
result.mStatus = WinsockServer::Result::Status::FAILED;
|
||||
result.mErrorCode = server_socket->getState().mErrorCode;
|
||||
result.mErrorMessage = server_socket->getState().mErrorMessage;
|
||||
mFailedCallback(result);
|
||||
}
|
||||
if (server_socket->getState().mBindStatus == Socket::State::BindStatus::FAILED)
|
||||
{
|
||||
WinsockServer::Result result;
|
||||
result.mStatus = WinsockServer::Result::Status::FAILED;
|
||||
result.mErrorCode = server_socket->getState().mErrorCode;
|
||||
result.mErrorMessage = server_socket->getState().mErrorMessage;
|
||||
mFailedCallback(result);
|
||||
}
|
||||
}
|
||||
|
||||
void WinsockServer::shutDown()
|
||||
{
|
||||
mThreads.removeMarked();
|
||||
mThreads.joinAndClearAll();
|
||||
mThreads.removeMarked();
|
||||
mThreads.joinAndClearAll();
|
||||
}
|
||||
|
||||
void WinsockServer::onConnection(std::unique_ptr<WinsockSocket> s)
|
||||
{
|
||||
// House-keeping first - clean up any finished threads
|
||||
MLOG_INFO("Before thread cleanup: " << mThreads.size());
|
||||
// House-keeping first - clean up any finished threads
|
||||
MLOG_INFO("Before thread cleanup: " << mThreads.size());
|
||||
|
||||
mThreads.removeMarked();
|
||||
mThreads.removeMarked();
|
||||
|
||||
MLOG_INFO("After thread cleanup: " << mThreads.size());
|
||||
MLOG_INFO("After thread cleanup: " << mThreads.size());
|
||||
|
||||
auto worker_func = [this](std::unique_ptr<WinsockSocket> s)
|
||||
{
|
||||
MLOG_INFO("Spawned thread for new connection");
|
||||
auto worker_func = [this](std::unique_ptr<WinsockSocket> s)
|
||||
{
|
||||
MLOG_INFO("Spawned thread for new connection");
|
||||
|
||||
mConnectionCallback(s.get());
|
||||
mConnectionCallback(s.get());
|
||||
|
||||
MLOG_INFO("Finished thread for new connection");
|
||||
this->onThreadComplete(std::this_thread::get_id());
|
||||
};
|
||||
MLOG_INFO("Finished thread for new connection");
|
||||
this->onThreadComplete(std::this_thread::get_id());
|
||||
};
|
||||
|
||||
auto worker = std::make_unique<std::thread>(worker_func, std::move(s));
|
||||
mThreads.add(std::move(worker));
|
||||
auto worker = std::make_unique<std::thread>(worker_func, std::move(s));
|
||||
mThreads.add(std::move(worker));
|
||||
};
|
||||
|
||||
void WinsockServer::onThreadComplete(std::thread::id id)
|
||||
{
|
||||
mThreads.markForRemoval(id);
|
||||
}
|
||||
mThreads.markForRemoval(id);
|
||||
}
|
||||
|
|
|
@ -12,20 +12,20 @@ class WinsockInterface;
|
|||
class WinsockServer : public PlatformSocketServer
|
||||
{
|
||||
public:
|
||||
virtual ~WinsockServer();
|
||||
virtual ~WinsockServer();
|
||||
|
||||
void listen(const Address& address, onConnectionSuccessFunc connectionSuccessFunc, onConnectionFailedFunc connectionFailedFunc) override;
|
||||
void listen(const Address& address, onConnectionSuccessFunc connectionSuccessFunc, onConnectionFailedFunc connectionFailedFunc) override;
|
||||
|
||||
void shutDown() override;
|
||||
void shutDown() override;
|
||||
|
||||
private:
|
||||
void onConnection(std::unique_ptr<WinsockSocket> clientHandle);
|
||||
void onConnection(std::unique_ptr<WinsockSocket> clientHandle);
|
||||
|
||||
void onThreadComplete(std::thread::id id);
|
||||
void onThreadComplete(std::thread::id id);
|
||||
|
||||
ThreadCollection mThreads;
|
||||
onConnectionSuccessFunc mConnectionCallback;
|
||||
onConnectionFailedFunc mFailedCallback;
|
||||
ThreadCollection mThreads;
|
||||
onConnectionSuccessFunc mConnectionCallback;
|
||||
onConnectionFailedFunc mFailedCallback;
|
||||
|
||||
std::unique_ptr<WinsockInterface> mWinsockInterface;
|
||||
};
|
||||
std::unique_ptr<WinsockInterface> mWinsockInterface;
|
||||
};
|
||||
|
|
|
@ -0,0 +1,184 @@
|
|||
#include "BerkeleySocket.h"
|
||||
|
||||
#include "FileLogger.h"
|
||||
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
BerkeleySocket::BerkeleySocket(const std::string& address, unsigned port)
|
||||
: Socket(address, port)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
BerkeleySocket::BerkeleySocket(int handle)
|
||||
: Socket("", 0),
|
||||
mHandle(handle)
|
||||
{
|
||||
mState.mConnectStatus = State::ConnectStatus::OK;
|
||||
}
|
||||
|
||||
BerkeleySocket::~BerkeleySocket()
|
||||
{
|
||||
MLOG_INFO("Socket being destroyed");
|
||||
}
|
||||
|
||||
void BerkeleySocket::initialize()
|
||||
{
|
||||
mHandle = ::socket(AF_INET, SOCK_STREAM, 0);
|
||||
}
|
||||
|
||||
void BerkeleySocket::initializeForBind()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void BerkeleySocket::doConnect()
|
||||
{
|
||||
struct sockaddr_in serv_addr;
|
||||
memset(&serv_addr, 0, sizeof(serv_addr));
|
||||
serv_addr.sin_family = AF_INET;
|
||||
|
||||
::inet_aton(mAddress.c_str(), &serv_addr.sin_addr);
|
||||
serv_addr.sin_port = ::htons(mPort);
|
||||
|
||||
int result = ::connect(mHandle, (struct sockaddr *)&serv_addr, sizeof(serv_addr));
|
||||
if( result < 0)
|
||||
{
|
||||
mState.mConnectStatus = Socket::State::ConnectStatus::FAILED;
|
||||
mState.mErrorCode = result;
|
||||
mState.mErrorMessage = "Socket: Unable to connect to server.";
|
||||
return;
|
||||
}
|
||||
mState.mConnectStatus = Socket::State::ConnectStatus::OK;
|
||||
}
|
||||
|
||||
void BerkeleySocket::doBind()
|
||||
{
|
||||
struct sockaddr_in serv_addr;
|
||||
memset(&serv_addr, 0, sizeof(serv_addr));
|
||||
serv_addr.sin_family = AF_INET;
|
||||
serv_addr.sin_addr.s_addr = INADDR_ANY;
|
||||
serv_addr.sin_port = htons(mPort);
|
||||
|
||||
int result = ::bind(mHandle, (struct sockaddr *)&serv_addr, sizeof(serv_addr));
|
||||
if (result< 0)
|
||||
{
|
||||
mState.mBindStatus = Socket::State::BindStatus::FAILED;
|
||||
mState.mErrorCode = result;
|
||||
mState.mErrorMessage = "Socket: Unable to bind socket";
|
||||
return;
|
||||
}
|
||||
mState.mBindStatus = Socket::State::BindStatus::OK;
|
||||
}
|
||||
|
||||
void BerkeleySocket::doListen(onIncomingConnectionFunc connectionFunc)
|
||||
{
|
||||
initializeForBind();
|
||||
if (mState.mBindStatus == Socket::State::BindStatus::FAILED)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
doBind();
|
||||
if (mState.mBindStatus == Socket::State::BindStatus::FAILED)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
::listen(mHandle, 5);
|
||||
|
||||
struct sockaddr_in cli_addr;
|
||||
socklen_t clilen = sizeof(cli_addr);
|
||||
while(true)
|
||||
{
|
||||
const auto new_socket_handle = ::accept(mHandle, (struct sockaddr *) &cli_addr, &clilen);
|
||||
if (new_socket_handle < 0)
|
||||
{
|
||||
mState.mBindStatus = Socket::State::BindStatus::FAILED;
|
||||
mState.mErrorCode = new_socket_handle;
|
||||
mState.mErrorMessage = "Socket: Accept failed";
|
||||
::close(mHandle);
|
||||
return;
|
||||
}
|
||||
connectionFunc(new_socket_handle);
|
||||
}
|
||||
}
|
||||
|
||||
std::string BerkeleySocket::send(const std::string& message)
|
||||
{
|
||||
if (mState.mConnectStatus != Socket::State::ConnectStatus::OK)
|
||||
{
|
||||
initialize();
|
||||
if (mState.mConnectStatus == Socket::State::ConnectStatus::FAILED)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
doConnect();
|
||||
if (mState.mConnectStatus == Socket::State::ConnectStatus::FAILED)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
auto n = ::write(mHandle, message.c_str(), message.length());
|
||||
if (n < 0)
|
||||
{
|
||||
onSockerError("Socket: Send failed.");
|
||||
return{};
|
||||
}
|
||||
|
||||
std::string response;
|
||||
while (mState.mConnectStatus == Socket::State::ConnectStatus::OK)
|
||||
{
|
||||
response += recieve();
|
||||
}
|
||||
::close(mHandle);
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
void BerkeleySocket::respond(const std::string& message)
|
||||
{
|
||||
auto result = ::write(mHandle, message.c_str(), static_cast<int>(message.size()));
|
||||
(void)result;
|
||||
}
|
||||
|
||||
void BerkeleySocket::onSockerError(const std::string& message)
|
||||
{
|
||||
mState.mErrorCode = -1;
|
||||
mState.mErrorMessage = message;
|
||||
|
||||
if (mState.mConnectStatus == Socket::State::ConnectStatus::OK)
|
||||
{
|
||||
::close(mHandle);
|
||||
}
|
||||
mState.mConnectStatus = Socket::State::ConnectStatus::FAILED;
|
||||
}
|
||||
|
||||
std::string BerkeleySocket::recieve()
|
||||
{
|
||||
const int BUFFER_SIZE = 512;
|
||||
char buffer[BUFFER_SIZE];
|
||||
auto result = ::read(mHandle, buffer, BUFFER_SIZE);
|
||||
if (result > 0)
|
||||
{
|
||||
return std::string(buffer);
|
||||
}
|
||||
else if (result == 0)
|
||||
{
|
||||
mState.mConnectStatus = Socket::State::ConnectStatus::UNSET;
|
||||
}
|
||||
else
|
||||
{
|
||||
mState.mConnectStatus = Socket::State::ConnectStatus::FAILED;
|
||||
mState.mErrorCode = result;
|
||||
mState.mErrorMessage = "Socket: read failed.";
|
||||
}
|
||||
return {};
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
#pragma once
|
||||
|
||||
#include "Socket.h"
|
||||
|
||||
#include <string>
|
||||
#include <functional>
|
||||
|
||||
class BerkeleySocket : public Socket
|
||||
{
|
||||
public:
|
||||
BerkeleySocket(const std::string& address, unsigned port);
|
||||
|
||||
BerkeleySocket(int handle);
|
||||
|
||||
~BerkeleySocket();
|
||||
|
||||
std::string recieve() override;
|
||||
|
||||
void respond(const std::string& message) override;
|
||||
|
||||
std::string send(const std::string& message) override;
|
||||
|
||||
using onIncomingConnectionFunc = std::function<void(int)>;
|
||||
void doListen(onIncomingConnectionFunc connectionFunc);
|
||||
|
||||
private:
|
||||
void initialize() override;
|
||||
void initializeForBind() override;
|
||||
|
||||
void doConnect() override;
|
||||
|
||||
void doBind() override;
|
||||
|
||||
void onSockerError(const std::string& message);
|
||||
|
||||
int mHandle{ 0 };
|
||||
};
|
|
@ -1,17 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
class Socket;
|
||||
using SocketPtr = std::unique_ptr<Socket>;
|
||||
|
||||
class ISocketInterface
|
||||
{
|
||||
public:
|
||||
ISocketInterface() = default;
|
||||
|
||||
virtual ~ISocketInterface() = default;
|
||||
};
|
||||
|
||||
using ISocketInterfaceUPtr = std::unique_ptr<ISocketInterface>;
|
|
@ -1,146 +0,0 @@
|
|||
#include "UnixSocketInterface.h"
|
||||
|
||||
#include "HttpResponse.h"
|
||||
#include "HttpMessageHandler.h"
|
||||
|
||||
#include "FileLogger.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
UnixSocketInterface::UnixSocketInterface()
|
||||
{
|
||||
mMessageHandler = std::make_unique<HttpMessageHandler>();
|
||||
}
|
||||
|
||||
std::unique_ptr<UnixSocketInterface> UnixSocketInterface::Create()
|
||||
{
|
||||
return std::make_unique<UnixSocketInterface>();
|
||||
}
|
||||
|
||||
UnixSocketInterface::~UnixSocketInterface()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void UnixSocketInterface::initializeSocket(const SocketPtr& socketPtr, const std::string& address)
|
||||
{
|
||||
auto handle = ::socket(AF_INET, SOCK_STREAM, 0);
|
||||
socketPtr->setHandle(handle);
|
||||
|
||||
if (!address.empty())
|
||||
{
|
||||
socketPtr->setAddress(address);
|
||||
}
|
||||
}
|
||||
|
||||
void UnixSocketInterface::socketWrite(const SocketPtr& socket, const std::string& message)
|
||||
{
|
||||
if(socket->getHandle() < 0)
|
||||
{
|
||||
MLOG_ERROR("Error opening socket" );
|
||||
return;
|
||||
}
|
||||
|
||||
const auto port = static_cast<int>(socket->getPort());
|
||||
struct sockaddr_in serv_addr;
|
||||
memset(&serv_addr, 0, sizeof(serv_addr));
|
||||
serv_addr.sin_family = AF_INET;
|
||||
|
||||
inet_aton(socket->getAddress().c_str(), &serv_addr.sin_addr);
|
||||
serv_addr.sin_port = htons(port);
|
||||
|
||||
int result = connect(socket->getHandle(), (struct sockaddr *)&serv_addr, sizeof(serv_addr));
|
||||
if(result< 0)
|
||||
{
|
||||
MLOG_ERROR("Error connecting to socket" );
|
||||
return;
|
||||
}
|
||||
|
||||
auto n = write(socket->getHandle(), message.c_str(), message.length());
|
||||
if (n < 0)
|
||||
{
|
||||
std::cerr << "Error on write" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
char buffer[BUFFER_SIZE] = {0};
|
||||
int res = read(socket->getHandle(), buffer, BUFFER_SIZE);
|
||||
if (res < 0)
|
||||
{
|
||||
std::cerr << "Error on read" << std::endl;
|
||||
return;
|
||||
}
|
||||
socket->setMessage(buffer);
|
||||
std::cout << "Here is the message: " << buffer << std::endl;
|
||||
}
|
||||
|
||||
void UnixSocketInterface::socketListen(const SocketPtr& socket)
|
||||
{
|
||||
if(socket->getHandle() < 0)
|
||||
{
|
||||
std::cerr << "Error opening socket" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
const auto port = static_cast<int>(socket->getPort());
|
||||
struct sockaddr_in serv_addr;
|
||||
memset(&serv_addr, 0, sizeof(serv_addr));
|
||||
serv_addr.sin_family = AF_INET;
|
||||
serv_addr.sin_addr.s_addr = INADDR_ANY;
|
||||
serv_addr.sin_port = htons(port);
|
||||
|
||||
int result = bind(socket->getHandle(), (struct sockaddr *)&serv_addr, sizeof(serv_addr));
|
||||
if(result< 0)
|
||||
{
|
||||
std::cerr << "Error binding socket" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
listen(socket->getHandle(), 5);
|
||||
}
|
||||
|
||||
void UnixSocketInterface::run(const SocketPtr& socket)
|
||||
{
|
||||
if(socket->getHandle() < 0)
|
||||
{
|
||||
std::cerr << "Error opening socket" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
struct sockaddr_in cli_addr;
|
||||
socklen_t clilen = sizeof(cli_addr);
|
||||
while(true)
|
||||
{
|
||||
const auto new_socket_handle = accept(socket->getHandle(), (struct sockaddr *) &cli_addr, &clilen);
|
||||
if (new_socket_handle < 0)
|
||||
{
|
||||
std::cerr << "Error on accept" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
char buffer[BUFFER_SIZE] = {0};
|
||||
int n = read(new_socket_handle, buffer, BUFFER_SIZE);
|
||||
if (n < 0)
|
||||
{
|
||||
std::cerr << "Error on read" << std::endl;
|
||||
return;
|
||||
}
|
||||
socket->setMessage(buffer);
|
||||
std::cout << "Here is the message: " << buffer << std::endl;
|
||||
|
||||
const auto response = mMessageHandler->onMessage(buffer);
|
||||
n = write(new_socket_handle, response.c_str(), response.length());
|
||||
if (n < 0)
|
||||
{
|
||||
std::cerr << "Error on write" << std::endl;
|
||||
return;
|
||||
}
|
||||
close(new_socket_handle);
|
||||
}
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include "Socket.h"
|
||||
#include "SocketInterface.h"
|
||||
|
||||
#include <memory>
|
||||
#include <map>
|
||||
|
||||
class ISocketMessageHandler;
|
||||
|
||||
class UnixSocketInterface : public ISocketInterface
|
||||
{
|
||||
public:
|
||||
UnixSocketInterface();
|
||||
|
||||
virtual ~UnixSocketInterface();
|
||||
|
||||
static std::unique_ptr<UnixSocketInterface> Create();
|
||||
|
||||
void initializeSocket(const SocketPtr& socket, const std::string& address = {}) override;
|
||||
|
||||
void socketListen(const SocketPtr& socket) override;
|
||||
|
||||
void socketWrite(const SocketPtr& socket, const std::string& message) override;
|
||||
|
||||
void run(const SocketPtr& socket) override;
|
||||
|
||||
private:
|
||||
static constexpr unsigned BUFFER_SIZE{1024};
|
||||
std::unique_ptr<ISocketMessageHandler> mMessageHandler;
|
||||
};
|
||||
|
||||
using UnixSocketInterfacePtr = std::unique_ptr<UnixSocketInterface>;
|
|
@ -1,8 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include "SocketInterface.h"
|
||||
|
||||
class WinsockInterface : public ISocketInterface
|
||||
class WinsockInterface
|
||||
{
|
||||
public:
|
||||
~WinsockInterface();
|
||||
|
@ -10,4 +8,4 @@ public:
|
|||
bool initializeWinsock();
|
||||
|
||||
void closeWinsock();
|
||||
};
|
||||
};
|
||||
|
|
|
@ -6,240 +6,240 @@
|
|||
#include "FileLogger.h"
|
||||
|
||||
WinsockSocket::WinsockSocket(const std::string& address, unsigned port)
|
||||
: Socket(address, port)
|
||||
: Socket(address, port)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
WinsockSocket::WinsockSocket(SOCKET handle)
|
||||
: Socket("", 0),
|
||||
mHandle(handle)
|
||||
: Socket("", 0),
|
||||
mHandle(handle)
|
||||
{
|
||||
mState.mConnectStatus = State::ConnectStatus::OK;
|
||||
mState.mConnectStatus = State::ConnectStatus::OK;
|
||||
}
|
||||
|
||||
WinsockSocket::~WinsockSocket()
|
||||
{
|
||||
MLOG_INFO("Socket being destroyed");
|
||||
MLOG_INFO("Socket being destroyed");
|
||||
}
|
||||
|
||||
void WinsockSocket::initialize()
|
||||
{
|
||||
addrinfo hints;
|
||||
ZeroMemory(&hints, sizeof(hints));
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
hints.ai_protocol = IPPROTO_TCP;
|
||||
addrinfo hints;
|
||||
ZeroMemory(&hints, sizeof(hints));
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
hints.ai_protocol = IPPROTO_TCP;
|
||||
|
||||
auto result = ::getaddrinfo(mAddress.c_str(), std::to_string(mPort).c_str(), &hints, &mAddressInfo);
|
||||
if (result != 0)
|
||||
{
|
||||
mState.mConnectStatus = Socket::State::ConnectStatus::FAILED;
|
||||
mState.mErrorCode = result;
|
||||
mState.mErrorMessage = "WinsockSocket: getaddrinfo failed for connect";
|
||||
return;
|
||||
}
|
||||
auto result = ::getaddrinfo(mAddress.c_str(), std::to_string(mPort).c_str(), &hints, &mAddressInfo);
|
||||
if (result != 0)
|
||||
{
|
||||
mState.mConnectStatus = Socket::State::ConnectStatus::FAILED;
|
||||
mState.mErrorCode = result;
|
||||
mState.mErrorMessage = "WinsockSocket: getaddrinfo failed for connect";
|
||||
return;
|
||||
}
|
||||
|
||||
mHandle = ::socket(mAddressInfo->ai_family, mAddressInfo->ai_socktype, mAddressInfo->ai_protocol);
|
||||
if (mHandle == INVALID_SOCKET)
|
||||
{
|
||||
onSockerError("WinsockSocket: Error at socket()");
|
||||
::freeaddrinfo(mAddressInfo);
|
||||
return;
|
||||
}
|
||||
mHandle = ::socket(mAddressInfo->ai_family, mAddressInfo->ai_socktype, mAddressInfo->ai_protocol);
|
||||
if (mHandle == INVALID_SOCKET)
|
||||
{
|
||||
onSockerError("WinsockSocket: Error at socket()");
|
||||
::freeaddrinfo(mAddressInfo);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void WinsockSocket::initializeForBind()
|
||||
{
|
||||
addrinfo hints;
|
||||
ZeroMemory(&hints, sizeof(hints));
|
||||
hints.ai_family = AF_INET;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
hints.ai_protocol = IPPROTO_TCP;
|
||||
hints.ai_flags = AI_PASSIVE;
|
||||
addrinfo hints;
|
||||
ZeroMemory(&hints, sizeof(hints));
|
||||
hints.ai_family = AF_INET;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
hints.ai_protocol = IPPROTO_TCP;
|
||||
hints.ai_flags = AI_PASSIVE;
|
||||
|
||||
// https://learn.microsoft.com/en-us/windows/win32/winsock/windows-sockets-error-codes-2
|
||||
auto result = ::getaddrinfo(nullptr, std::to_string(mPort).c_str(), &hints, &mAddressInfo);
|
||||
if (result != 0)
|
||||
{
|
||||
mState.mBindStatus = Socket::State::BindStatus::FAILED;
|
||||
mState.mErrorCode = result;
|
||||
mState.mErrorMessage = "WinsockSocket: getaddrinfo failed for bind";
|
||||
return;
|
||||
}
|
||||
// https://learn.microsoft.com/en-us/windows/win32/winsock/windows-sockets-error-codes-2
|
||||
auto result = ::getaddrinfo(nullptr, std::to_string(mPort).c_str(), &hints, &mAddressInfo);
|
||||
if (result != 0)
|
||||
{
|
||||
mState.mBindStatus = Socket::State::BindStatus::FAILED;
|
||||
mState.mErrorCode = result;
|
||||
mState.mErrorMessage = "WinsockSocket: getaddrinfo failed for bind";
|
||||
return;
|
||||
}
|
||||
|
||||
mHandle = ::socket(mAddressInfo->ai_family, mAddressInfo->ai_socktype, mAddressInfo->ai_protocol);
|
||||
if (mHandle == INVALID_SOCKET)
|
||||
{
|
||||
onSockerError("WinsockSocket: Error at socket()");
|
||||
::freeaddrinfo(mAddressInfo);
|
||||
return;
|
||||
}
|
||||
mHandle = ::socket(mAddressInfo->ai_family, mAddressInfo->ai_socktype, mAddressInfo->ai_protocol);
|
||||
if (mHandle == INVALID_SOCKET)
|
||||
{
|
||||
onSockerError("WinsockSocket: Error at socket()");
|
||||
::freeaddrinfo(mAddressInfo);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void WinsockSocket::doConnect()
|
||||
{
|
||||
auto result = ::connect(mHandle, mAddressInfo->ai_addr, (int)mAddressInfo->ai_addrlen);
|
||||
if (result == SOCKET_ERROR)
|
||||
{
|
||||
::closesocket(mHandle);
|
||||
mHandle = INVALID_SOCKET;
|
||||
}
|
||||
auto result = ::connect(mHandle, mAddressInfo->ai_addr, (int)mAddressInfo->ai_addrlen);
|
||||
if (result == SOCKET_ERROR)
|
||||
{
|
||||
::closesocket(mHandle);
|
||||
mHandle = INVALID_SOCKET;
|
||||
}
|
||||
|
||||
::freeaddrinfo(mAddressInfo);
|
||||
::freeaddrinfo(mAddressInfo);
|
||||
|
||||
if (mHandle == INVALID_SOCKET)
|
||||
{
|
||||
mState.mConnectStatus = Socket::State::ConnectStatus::FAILED;
|
||||
mState.mErrorCode = SOCKET_ERROR;
|
||||
mState.mErrorMessage = "WinsockSocket: Unable to connect to server.";
|
||||
return;
|
||||
}
|
||||
mState.mConnectStatus = Socket::State::ConnectStatus::OK;
|
||||
if (mHandle == INVALID_SOCKET)
|
||||
{
|
||||
mState.mConnectStatus = Socket::State::ConnectStatus::FAILED;
|
||||
mState.mErrorCode = SOCKET_ERROR;
|
||||
mState.mErrorMessage = "WinsockSocket: Unable to connect to server.";
|
||||
return;
|
||||
}
|
||||
mState.mConnectStatus = Socket::State::ConnectStatus::OK;
|
||||
}
|
||||
|
||||
void WinsockSocket::doBind()
|
||||
{
|
||||
auto result = ::bind(mHandle, mAddressInfo->ai_addr, (int)mAddressInfo->ai_addrlen);
|
||||
if (result == SOCKET_ERROR)
|
||||
{
|
||||
::closesocket(mHandle);
|
||||
mHandle = INVALID_SOCKET;
|
||||
}
|
||||
auto result = ::bind(mHandle, mAddressInfo->ai_addr, (int)mAddressInfo->ai_addrlen);
|
||||
if (result == SOCKET_ERROR)
|
||||
{
|
||||
::closesocket(mHandle);
|
||||
mHandle = INVALID_SOCKET;
|
||||
}
|
||||
|
||||
::freeaddrinfo(mAddressInfo);
|
||||
::freeaddrinfo(mAddressInfo);
|
||||
|
||||
if (mHandle == INVALID_SOCKET)
|
||||
{
|
||||
mState.mBindStatus = Socket::State::BindStatus::FAILED;
|
||||
mState.mErrorCode = ::WSAGetLastError();
|
||||
mState.mErrorMessage = "WinsockSocket: Unable to bind socket";
|
||||
return;
|
||||
}
|
||||
mState.mBindStatus = Socket::State::BindStatus::OK;
|
||||
if (mHandle == INVALID_SOCKET)
|
||||
{
|
||||
mState.mBindStatus = Socket::State::BindStatus::FAILED;
|
||||
mState.mErrorCode = ::WSAGetLastError();
|
||||
mState.mErrorMessage = "WinsockSocket: Unable to bind socket";
|
||||
return;
|
||||
}
|
||||
mState.mBindStatus = Socket::State::BindStatus::OK;
|
||||
}
|
||||
|
||||
void WinsockSocket::doListen(onIncomingConnectionFunc connectionFunc)
|
||||
{
|
||||
initializeForBind();
|
||||
if (mState.mBindStatus == Socket::State::BindStatus::FAILED)
|
||||
{
|
||||
return;
|
||||
}
|
||||
initializeForBind();
|
||||
if (mState.mBindStatus == Socket::State::BindStatus::FAILED)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
doBind();
|
||||
if (mState.mBindStatus == Socket::State::BindStatus::FAILED)
|
||||
{
|
||||
return;
|
||||
}
|
||||
doBind();
|
||||
if (mState.mBindStatus == Socket::State::BindStatus::FAILED)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (::listen(mHandle, SOMAXCONN) == SOCKET_ERROR)
|
||||
{
|
||||
mState.mBindStatus = Socket::State::BindStatus::FAILED;
|
||||
mState.mErrorCode = ::WSAGetLastError();
|
||||
mState.mErrorMessage = "WinsockSocket: Listen failed";
|
||||
::closesocket(mHandle);
|
||||
return;
|
||||
}
|
||||
if (::listen(mHandle, SOMAXCONN) == SOCKET_ERROR)
|
||||
{
|
||||
mState.mBindStatus = Socket::State::BindStatus::FAILED;
|
||||
mState.mErrorCode = ::WSAGetLastError();
|
||||
mState.mErrorMessage = "WinsockSocket: Listen failed";
|
||||
::closesocket(mHandle);
|
||||
return;
|
||||
}
|
||||
|
||||
while (true)
|
||||
{
|
||||
auto client_handle = ::accept(mHandle, NULL, NULL);
|
||||
if (client_handle == INVALID_SOCKET)
|
||||
{
|
||||
mState.mBindStatus = Socket::State::BindStatus::FAILED;
|
||||
mState.mErrorCode = ::WSAGetLastError();
|
||||
mState.mErrorMessage = "WinsockSocket: Accept failed";
|
||||
::closesocket(mHandle);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
connectionFunc(client_handle);
|
||||
}
|
||||
}
|
||||
while (true)
|
||||
{
|
||||
auto client_handle = ::accept(mHandle, NULL, NULL);
|
||||
if (client_handle == INVALID_SOCKET)
|
||||
{
|
||||
mState.mBindStatus = Socket::State::BindStatus::FAILED;
|
||||
mState.mErrorCode = ::WSAGetLastError();
|
||||
mState.mErrorMessage = "WinsockSocket: Accept failed";
|
||||
::closesocket(mHandle);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
connectionFunc(client_handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string WinsockSocket::send(const std::string& message)
|
||||
{
|
||||
if (mState.mConnectStatus != Socket::State::ConnectStatus::OK)
|
||||
{
|
||||
initialize();
|
||||
if (mState.mConnectStatus == Socket::State::ConnectStatus::FAILED)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
if (mState.mConnectStatus != Socket::State::ConnectStatus::OK)
|
||||
{
|
||||
initialize();
|
||||
if (mState.mConnectStatus == Socket::State::ConnectStatus::FAILED)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
doConnect();
|
||||
if (mState.mConnectStatus == Socket::State::ConnectStatus::FAILED)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
}
|
||||
doConnect();
|
||||
if (mState.mConnectStatus == Socket::State::ConnectStatus::FAILED)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
auto result = ::send(mHandle, message.c_str(), static_cast<int>(message.size()), 0);
|
||||
if (result == SOCKET_ERROR)
|
||||
{
|
||||
onSockerError("WinsockSocket: Send failed.");
|
||||
return {};
|
||||
}
|
||||
auto result = ::send(mHandle, message.c_str(), static_cast<int>(message.size()), 0);
|
||||
if (result == SOCKET_ERROR)
|
||||
{
|
||||
onSockerError("WinsockSocket: Send failed.");
|
||||
return {};
|
||||
}
|
||||
|
||||
result = ::shutdown(mHandle, SD_SEND);
|
||||
if (result == SOCKET_ERROR)
|
||||
{
|
||||
onSockerError("WinsockSocket: Post send shutdown failed.");
|
||||
return {};
|
||||
}
|
||||
result = ::shutdown(mHandle, SD_SEND);
|
||||
if (result == SOCKET_ERROR)
|
||||
{
|
||||
onSockerError("WinsockSocket: Post send shutdown failed.");
|
||||
return {};
|
||||
}
|
||||
|
||||
std::string response;
|
||||
while (mState.mConnectStatus == Socket::State::ConnectStatus::OK)
|
||||
{
|
||||
response += recieve();
|
||||
}
|
||||
::closesocket(mHandle);
|
||||
std::string response;
|
||||
while (mState.mConnectStatus == Socket::State::ConnectStatus::OK)
|
||||
{
|
||||
response += recieve();
|
||||
}
|
||||
::closesocket(mHandle);
|
||||
|
||||
return response;
|
||||
return response;
|
||||
}
|
||||
|
||||
void WinsockSocket::respond(const std::string& message)
|
||||
{
|
||||
auto result = ::send(mHandle, message.c_str(), static_cast<int>(message.size()), 0);
|
||||
if (result == SOCKET_ERROR)
|
||||
{
|
||||
onSockerError("WinsockSocket: Respond failed.");
|
||||
}
|
||||
auto result = ::send(mHandle, message.c_str(), static_cast<int>(message.size()), 0);
|
||||
if (result == SOCKET_ERROR)
|
||||
{
|
||||
onSockerError("WinsockSocket: Respond failed.");
|
||||
}
|
||||
}
|
||||
|
||||
void WinsockSocket::onSockerError(const std::string& message)
|
||||
{
|
||||
mState.mErrorCode = ::WSAGetLastError();
|
||||
mState.mErrorMessage = message;
|
||||
mState.mErrorCode = ::WSAGetLastError();
|
||||
mState.mErrorMessage = message;
|
||||
|
||||
if (mState.mConnectStatus == Socket::State::ConnectStatus::OK)
|
||||
{
|
||||
::closesocket(mHandle);
|
||||
}
|
||||
mState.mConnectStatus = Socket::State::ConnectStatus::FAILED;
|
||||
if (mState.mConnectStatus == Socket::State::ConnectStatus::OK)
|
||||
{
|
||||
::closesocket(mHandle);
|
||||
}
|
||||
mState.mConnectStatus = Socket::State::ConnectStatus::FAILED;
|
||||
}
|
||||
|
||||
std::string WinsockSocket::recieve()
|
||||
{
|
||||
const int BUFFER_SIZE = 512;
|
||||
char buffer[BUFFER_SIZE];
|
||||
auto result = ::recv(mHandle, buffer, BUFFER_SIZE, 0);
|
||||
if (result > 0)
|
||||
{
|
||||
return std::string(buffer);
|
||||
}
|
||||
else if (result == 0)
|
||||
{
|
||||
mState.mConnectStatus = Socket::State::ConnectStatus::UNSET;
|
||||
}
|
||||
else
|
||||
{
|
||||
mState.mConnectStatus = Socket::State::ConnectStatus::FAILED;
|
||||
mState.mErrorCode = ::WSAGetLastError();
|
||||
mState.mErrorMessage = "WinsockSocket: recv failed.";
|
||||
}
|
||||
return {};
|
||||
const int BUFFER_SIZE = 512;
|
||||
char buffer[BUFFER_SIZE];
|
||||
auto result = ::recv(mHandle, buffer, BUFFER_SIZE, 0);
|
||||
if (result > 0)
|
||||
{
|
||||
return std::string(buffer);
|
||||
}
|
||||
else if (result == 0)
|
||||
{
|
||||
mState.mConnectStatus = Socket::State::ConnectStatus::UNSET;
|
||||
}
|
||||
else
|
||||
{
|
||||
mState.mConnectStatus = Socket::State::ConnectStatus::FAILED;
|
||||
mState.mErrorCode = ::WSAGetLastError();
|
||||
mState.mErrorMessage = "WinsockSocket: recv failed.";
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
|
|
@ -9,32 +9,32 @@
|
|||
class WinsockSocket : public Socket
|
||||
{
|
||||
public:
|
||||
WinsockSocket(const std::string& address, unsigned port);
|
||||
WinsockSocket(const std::string& address, unsigned port);
|
||||
|
||||
WinsockSocket(SOCKET handle);
|
||||
WinsockSocket(SOCKET handle);
|
||||
|
||||
~WinsockSocket();
|
||||
~WinsockSocket();
|
||||
|
||||
std::string recieve() override;
|
||||
std::string recieve() override;
|
||||
|
||||
void respond(const std::string& message) override;
|
||||
void respond(const std::string& message) override;
|
||||
|
||||
std::string send(const std::string& message) override;
|
||||
std::string send(const std::string& message) override;
|
||||
|
||||
using onIncomingConnectionFunc = std::function<void(SOCKET)>;
|
||||
void doListen(onIncomingConnectionFunc connectionFunc);
|
||||
using onIncomingConnectionFunc = std::function<void(SOCKET)>;
|
||||
void doListen(onIncomingConnectionFunc connectionFunc);
|
||||
|
||||
private:
|
||||
void initialize() override;
|
||||
void initializeForBind() override;
|
||||
void initialize() override;
|
||||
void initializeForBind() override;
|
||||
|
||||
void doConnect() override;
|
||||
void doConnect() override;
|
||||
|
||||
void doBind() override;
|
||||
void doBind() override;
|
||||
|
||||
void onSockerError(const std::string& message);
|
||||
void onSockerError(const std::string& message);
|
||||
|
||||
SOCKET mHandle{ INVALID_SOCKET };
|
||||
SOCKET mHandle{ INVALID_SOCKET };
|
||||
|
||||
addrinfo* mAddressInfo{ nullptr };
|
||||
};
|
||||
addrinfo* mAddressInfo{ nullptr };
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue