Skip to content

Commit

Permalink
adapt UPD and Pipe to SimpleConnection interface
Browse files Browse the repository at this point in the history
  • Loading branch information
markaren committed Sep 24, 2024
1 parent 5085582 commit 979d80c
Show file tree
Hide file tree
Showing 17 changed files with 223 additions and 85 deletions.
19 changes: 11 additions & 8 deletions include/simple_socket/Pipe.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@
#ifndef SIMPLE_SOCKET_PIPE_HPP
#define SIMPLE_SOCKET_PIPE_HPP

#include "SimpleConnection.hpp"

#include <memory>
#include <string>
#include <vector>

namespace simple_socket {

class NamedPipe {
class NamedPipe: SimpleConnection {

struct PassKey {
friend class NamedPipe;
Expand All @@ -22,17 +23,19 @@ namespace simple_socket {
NamedPipe(NamedPipe& other) = delete;
NamedPipe& operator=(NamedPipe& other) = delete;

bool send(const std::string& message);

bool send(const std::vector<unsigned char>& data);

int receive(std::vector<unsigned char>& buffer);
int read(std::vector<unsigned char>& buffer) override;
int read(unsigned char* buffer, size_t size) override;
bool readExact(std::vector<unsigned char>& buffer) override;
bool readExact(unsigned char* buffer, size_t size) override;
bool write(const std::string& message) override;
bool write(const std::vector<unsigned char>& data) override;
void close() override;

static std::unique_ptr<NamedPipe> listen(const std::string& name);

static std::unique_ptr<NamedPipe> connect(const std::string& name, long timeOut = 5000);

~NamedPipe();
~NamedPipe() override;

private:
struct Impl;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,10 @@

#include <string>
#include <vector>
#include <memory>

namespace simple_socket {

class SocketConnection {
class SimpleConnection {
public:
virtual int read(std::vector<unsigned char>& buffer) = 0;

Expand All @@ -24,7 +23,7 @@ namespace simple_socket {

virtual void close() = 0;

virtual ~SocketConnection() = default;
virtual ~SimpleConnection() = default;
};

}// namespace simple_socket
Expand Down
8 changes: 5 additions & 3 deletions include/simple_socket/TCPSocket.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,17 @@
#ifndef SIMPLE_SOCKET_TCPSOCKET_HPP
#define SIMPLE_SOCKET_TCPSOCKET_HPP

#include "simple_socket/Socket.hpp"
#include "simple_socket/SimpleConnection.hpp"

#include <memory>

namespace simple_socket {

class TCPClientContext {
public:
TCPClientContext();

std::unique_ptr<SocketConnection> connect(const std::string& ip, int port);
std::unique_ptr<SimpleConnection> connect(const std::string& ip, int port);

~TCPClientContext();

Expand All @@ -23,7 +25,7 @@ namespace simple_socket {
public:
explicit TCPServer(int port, int backlog = 1);

std::unique_ptr<SocketConnection> accept();
std::unique_ptr<SimpleConnection> accept();

void close();

Expand Down
8 changes: 8 additions & 0 deletions include/simple_socket/UDPSocket.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
#include <string>
#include <vector>

#include "simple_socket/SimpleConnection.hpp"

#ifndef MAX_UDP_PACKET_SIZE
#define MAX_UDP_PACKET_SIZE 65507
#endif
Expand All @@ -20,10 +22,16 @@ namespace simple_socket {

bool sendTo(const std::string& address, uint16_t remotePort, const std::vector<unsigned char>& data);

bool sendTo(const std::string& address, uint16_t remotePort, const unsigned char* data, size_t size);

int recvFrom(const std::string& address, uint16_t remotePort, std::vector<unsigned char>& buffer);

int recvFrom(const std::string& address, uint16_t remotePort, unsigned char* buffer, size_t size);

[[nodiscard]] std::string recvFrom(const std::string& address, uint16_t remotePort);

std::unique_ptr<SimpleConnection> makeConnection(const std::string& address, uint16_t remotePort);

void close();

~UDPSocket();
Expand Down
6 changes: 3 additions & 3 deletions include/simple_socket/UnixDomainSocket.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#ifndef SIMPLE_SOCKET_UNIXDOMAINSOCKET_HPP
#define SIMPLE_SOCKET_UNIXDOMAINSOCKET_HPP

#include "simple_socket/Socket.hpp"
#include "simple_socket/SimpleConnection.hpp"

#include <memory>

Expand All @@ -12,7 +12,7 @@ namespace simple_socket {
public:
UnixDomainClientContext();

std::unique_ptr<SocketConnection> connect(const std::string& domain);
std::unique_ptr<SimpleConnection> connect(const std::string& domain);

~UnixDomainClientContext();
private:
Expand All @@ -24,7 +24,7 @@ namespace simple_socket {
public:
explicit UnixDomainServer(const std::string& domain, int backlog = 1);

std::unique_ptr<SocketConnection> accept();
std::unique_ptr<SimpleConnection> accept();

void close();

Expand Down
2 changes: 1 addition & 1 deletion src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ set(publicHeaderDir "${PROJECT_SOURCE_DIR}/include")
set(publicHeaders

"simple_socket/port_query.hpp"
"simple_socket/Socket.hpp"
"simple_socket/SimpleConnection.hpp"
"simple_socket/TCPSocket.hpp"
"simple_socket/UDPSocket.hpp"
"simple_socket/UnixDomainSocket.hpp"
Expand Down
86 changes: 56 additions & 30 deletions src/simple_socket/Pipe.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,18 @@ struct NamedPipe::Impl {

HANDLE hPipe_{INVALID_HANDLE_VALUE};

~Impl() {
void close() {
if (hPipe_ != INVALID_HANDLE_VALUE) {
CloseHandle(hPipe_);
hPipe_ = INVALID_HANDLE_VALUE;
}
}

~Impl() {

close();
}

static std::unique_ptr<NamedPipe> createPipe(HANDLE hPipe) {
auto pipe = std::make_unique<NamedPipe>(PassKey());
pipe->pimpl_->hPipe_ = hPipe;
Expand All @@ -35,35 +40,6 @@ NamedPipe::NamedPipe(NamedPipe&& other) noexcept: pimpl_(std::make_unique<Impl>(
other.pimpl_->hPipe_ = INVALID_HANDLE_VALUE;
}

bool NamedPipe::send(const std::string& message) {
DWORD bytesWritten;
if (!WriteFile(pimpl_->hPipe_, message.c_str(), message.size(), &bytesWritten, nullptr)) {
std::cerr << "Failed to write to pipe. Error: " << GetLastError() << std::endl;
return false;
}
return true;
}

bool NamedPipe::send(const std::vector<unsigned char>& data) {
DWORD bytesWritten;
if (!WriteFile(pimpl_->hPipe_, data.data(), data.size(), &bytesWritten, nullptr)) {
std::cerr << "Failed to write to pipe. Error: " << GetLastError() << std::endl;
return false;
}
return true;
}

int NamedPipe::receive(std::vector<unsigned char>& buffer) {

DWORD bytesRead;
if (!ReadFile(pimpl_->hPipe_, buffer.data(), buffer.size() - 1, &bytesRead, nullptr)) {
std::cerr << "Failed to read from pipe. Error: " << GetLastError() << std::endl;
return -1;
}
buffer[bytesRead] = '\0';
return static_cast<int>(bytesRead);
}

std::unique_ptr<NamedPipe> NamedPipe::listen(const std::string& name) {
const auto pipeName = R"(\\.\pipe\)" + name;
HANDLE hPipe = CreateNamedPipe(
Expand Down Expand Up @@ -129,4 +105,54 @@ std::unique_ptr<NamedPipe> NamedPipe::connect(const std::string& name, long time
}
}

int NamedPipe::read(std::vector<unsigned char>& buffer) {
DWORD bytesRead;
if (!ReadFile(pimpl_->hPipe_, buffer.data(), buffer.size() - 1, &bytesRead, nullptr)) {
std::cerr << "Failed to read from pipe. Error: " << GetLastError() << std::endl;
return -1;
}
buffer[bytesRead] = '\0';
return static_cast<int>(bytesRead);
}

int NamedPipe::read(unsigned char* buffer, size_t size) {
DWORD bytesRead;
if (!ReadFile(pimpl_->hPipe_, buffer, size - 1, &bytesRead, nullptr)) {
std::cerr << "Failed to read from pipe. Error: " << GetLastError() << std::endl;
return -1;
}
buffer[bytesRead] = '\0';
return static_cast<int>(bytesRead);
}

bool NamedPipe::readExact(std::vector<unsigned char>& buffer) {
throw std::runtime_error("Unsupported operation");
}

bool NamedPipe::readExact(unsigned char* buffer, size_t size) {
throw std::runtime_error("Unsupported operation");
}

bool NamedPipe::write(const std::string& message) {
DWORD bytesWritten;
if (!WriteFile(pimpl_->hPipe_, message.c_str(), message.size(), &bytesWritten, nullptr)) {
std::cerr << "Failed to write to pipe. Error: " << GetLastError() << std::endl;
return false;
}
return true;
}

bool NamedPipe::write(const std::vector<unsigned char>& data) {
DWORD bytesWritten;
if (!WriteFile(pimpl_->hPipe_, data.data(), data.size(), &bytesWritten, nullptr)) {
std::cerr << "Failed to write to pipe. Error: " << GetLastError() << std::endl;
return false;
}
return true;
}

void NamedPipe::close() {
pimpl_->close();
}

NamedPipe::~NamedPipe() = default;
14 changes: 7 additions & 7 deletions src/simple_socket/Socket.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

#include "simple_socket/Socket.hpp"
#include "simple_socket/SimpleConnection.hpp"
#include "simple_socket/TCPSocket.hpp"
#include "simple_socket/UnixDomainSocket.hpp"

Expand All @@ -20,7 +20,7 @@ namespace simple_socket {
return sockfd;
}

struct Socket: SocketConnection {
struct Socket: SimpleConnection {

explicit Socket(SOCKET socket)
: sockfd_(socket) {}
Expand Down Expand Up @@ -126,7 +126,7 @@ namespace simple_socket {
}
}

std::unique_ptr<SocketConnection> accept() {
std::unique_ptr<SimpleConnection> accept() {
sockaddr_in client_addr{};
socklen_t addrlen = sizeof(client_addr);
SOCKET new_sock = ::accept(socket.sockfd_, reinterpret_cast<sockaddr*>(&client_addr), &addrlen);
Expand Down Expand Up @@ -155,7 +155,7 @@ namespace simple_socket {
TCPServer::TCPServer(int port, int backlog)
: pimpl_(std::make_unique<Impl>(port, backlog)) {}

std::unique_ptr<SocketConnection> TCPServer::accept() {
std::unique_ptr<SimpleConnection> TCPServer::accept() {

return pimpl_->accept();
}
Expand All @@ -170,7 +170,7 @@ namespace simple_socket {
TCPClientContext::TCPClientContext()
: pimpl_(std::make_unique<Impl>()) {}

std::unique_ptr<SocketConnection> TCPClientContext::connect(const std::string& ip, int port) {
std::unique_ptr<SimpleConnection> TCPClientContext::connect(const std::string& ip, int port) {

SOCKET sock = createSocket(AF_INET, IPPROTO_TCP);

Expand Down Expand Up @@ -248,7 +248,7 @@ namespace simple_socket {
pimpl_->close();
}

std::unique_ptr<SocketConnection> UnixDomainServer::accept() {
std::unique_ptr<SimpleConnection> UnixDomainServer::accept() {

return pimpl_->accept();
}
Expand All @@ -266,7 +266,7 @@ namespace simple_socket {
: pimpl_(std::make_unique<Impl>()) {}


std::unique_ptr<SocketConnection> UnixDomainClientContext::connect(const std::string& domain) {
std::unique_ptr<SimpleConnection> UnixDomainClientContext::connect(const std::string& domain) {

SOCKET sockfd = createSocket(AF_UNIX, 0);

Expand Down
Loading

0 comments on commit 979d80c

Please sign in to comment.