Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
markaren committed May 15, 2024
1 parent 02f53f4 commit 0c1a9f4
Show file tree
Hide file tree
Showing 12 changed files with 140 additions and 74 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# SimpleSocket

A simple cross-platform Socket implementation for C++ (no external dependencies)
A simple cross-platform Socket (TCP/UDP) implementation for C++ (no external dependencies)
for education and hobby usage.


Expand Down
10 changes: 5 additions & 5 deletions include/Socket.hpp → include/TCPSocket.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ class Connection {
virtual ~Connection() = default;
};

class Socket: public Connection {
class TCPSocket: public Connection {
public:
Socket();
TCPSocket();

bool read(std::vector<unsigned char>& buffer, size_t* bytesRead) override;

Expand All @@ -43,7 +43,7 @@ class Socket: public Connection {

void close();

~Socket() override;
~TCPSocket() override;

protected:
void bind(int port);
Expand All @@ -59,12 +59,12 @@ class Socket: public Connection {
std::unique_ptr<Impl> pimpl_;
};

class ClientSocket: public Socket {
class TCPClient: public TCPSocket {
public:
bool connect(const std::string& ip, int port);
};

class ServerSocket: public Socket {
class TCPServer: public TCPSocket {
public:
void bind(int port);

Expand Down
4 changes: 2 additions & 2 deletions include/UDPSocket.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@

class UDPSocket{
public:
UDPSocket();
UDPSocket(int port);

void sendTo(const std::string& address, uint16_t port, const std::string& data);
bool sendTo(const std::string& address, uint16_t port, const std::string& data);

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

Expand Down
2 changes: 1 addition & 1 deletion src/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

add_library(simple_socket socket.cpp UDPSocket.cpp)
add_library(simple_socket TCPSocket.cpp UDPSocket.cpp)
target_compile_features(simple_socket PUBLIC "cxx_std_17")

if (WIN32)
Expand Down
48 changes: 24 additions & 24 deletions src/Socket.cpp → src/TCPSocket.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

#include "Socket.hpp"
#include "TCPSocket.hpp"

#ifdef _WIN32
#include <winsock2.h>
Expand All @@ -14,7 +14,7 @@ using SOCKET = int;
#include <iostream>
#include <stdexcept>

struct Socket::Impl {
struct TCPSocket::Impl {

Impl() {
#ifdef _WIN32
Expand Down Expand Up @@ -78,7 +78,7 @@ struct Socket::Impl {
}
#endif

auto conn = std::make_unique<Socket>();
auto conn = std::make_unique<TCPSocket>();
conn->pimpl_->assign(new_sock);

return conn;
Expand Down Expand Up @@ -174,81 +174,81 @@ struct Socket::Impl {
bool closed{false};
};

Socket::Socket(): pimpl_(std::make_unique<Impl>()) {}
TCPSocket::TCPSocket(): pimpl_(std::make_unique<Impl>()) {}

bool Socket::read(std::vector<unsigned char>& buffer, size_t* bytesRead) {
bool TCPSocket::read(std::vector<unsigned char>& buffer, size_t* bytesRead) {

return pimpl_->read(buffer.data(), buffer.size(), bytesRead);
}

bool Socket::read(unsigned char* buffer, size_t size, size_t* bytesRead) {
bool TCPSocket::read(unsigned char* buffer, size_t size, size_t* bytesRead) {

return pimpl_->read(buffer, size, bytesRead);
}

bool Socket::readExact(std::vector<unsigned char>& buffer) {
bool TCPSocket::readExact(std::vector<unsigned char>& buffer) {

return pimpl_->readExact(buffer.data(), buffer.size());
}

bool Socket::readExact(unsigned char* buffer, size_t size) {
bool TCPSocket::readExact(unsigned char* buffer, size_t size) {

return pimpl_->readExact(buffer, size);
}

bool Socket::write(const std::string& buffer) {
bool TCPSocket::write(const std::string& buffer) {

return pimpl_->write(buffer);
}

bool Socket::write(const std::vector<unsigned char>& buffer) {
bool TCPSocket::write(const std::vector<unsigned char>& buffer) {

return pimpl_->write(buffer);
}

bool Socket::connect(const std::string& ip, int port) {
bool TCPSocket::connect(const std::string& ip, int port) {

return pimpl_->connect(ip, port);
}

void Socket::bind(int port) {
void TCPSocket::bind(int port) {

pimpl_->bind(port);
}

void Socket::listen(int backlog) {
void TCPSocket::listen(int backlog) {

pimpl_->listen(backlog);
}

std::unique_ptr<Connection> Socket::accept() {
std::unique_ptr<Connection> TCPSocket::accept() {

return pimpl_->accept();
}

void Socket::close() {
void TCPSocket::close() {

pimpl_->close();
}

Socket::~Socket() = default;
TCPSocket::~TCPSocket() = default;

bool ClientSocket::connect(const std::string& ip, int port) {
bool TCPClient::connect(const std::string& ip, int port) {

return Socket::connect(ip, port);
return TCPSocket::connect(ip, port);
}

void ServerSocket::bind(int port) {
void TCPServer::bind(int port) {

Socket::bind(port);
TCPSocket::bind(port);
}

void ServerSocket::listen(int backlog) {
void TCPServer::listen(int backlog) {

Socket::listen(backlog);
TCPSocket::listen(backlog);
}

std::unique_ptr<Connection> ServerSocket::accept() {
std::unique_ptr<Connection> TCPServer::accept() {

return Socket::accept();
return TCPSocket::accept();
}
56 changes: 45 additions & 11 deletions src/UDPSocket.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
#ifdef _WIN32
#include <WS2tcpip.h>
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")
#else
#include <arpa/inet.h>
#include <sys/socket.h>
Expand All @@ -14,19 +13,44 @@
#define SOCKET_ERROR (-1)
#endif


#include <stdexcept>
#include <system_error>

struct UDPSocket::Impl {
Impl() {

explicit Impl(int port) {
#ifdef _WIN32
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
throw std::runtime_error("Failed to initialize winsock");

throw std::system_error(WSAGetLastError(), std::system_category(), "Failed to initialize winsock");
}
#endif

sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (sockfd == INVALID_SOCKET) {
#ifdef _WIN32
throw std::system_error(WSAGetLastError(), std::system_category(), "Failed to create socket");
#else
throw std::system_error(errno, std::generic_category(), "Failed to create socket");
#endif
}

sockaddr_in local{};
local.sin_family = AF_INET;
local.sin_addr.s_addr = INADDR_ANY;
local.sin_port = htons(port);

if (::bind(sockfd, (sockaddr*) &local, sizeof(local)) == SOCKET_ERROR) {
#if WIN32
throw std::system_error(WSAGetLastError(), std::system_category(), "Bind failed");
#else
throw std::system_error(errno, std::generic_category(), "Bind failed");
#endif
}
}

void bind(int port) {
}

bool sendTo(const std::string& address, uint16_t port, const std::string& data) {
Expand All @@ -37,10 +61,11 @@ struct UDPSocket::Impl {
return false;
}

return (sendto(sockfd, data.c_str(), data.size(), 0, (struct sockaddr*) &to, sizeof(to)) != SOCKET_ERROR);
return sendto(sockfd, data.c_str(), data.size(), 0, (sockaddr*) &to, sizeof(to)) != SOCKET_ERROR;
}

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

sockaddr_in from{};
from.sin_family = AF_INET;
from.sin_port = htons(port);
Expand All @@ -49,7 +74,12 @@ struct UDPSocket::Impl {
}
socklen_t fromLength = sizeof(from);

return recvfrom(sockfd, reinterpret_cast<char*>(buffer.data()), buffer.size(), 0, (struct sockaddr*) &from, &fromLength);
int receive = recvfrom(sockfd, reinterpret_cast<char*>(buffer.data()), buffer.size(), 0, (sockaddr*) &from, &fromLength);
if (receive == SOCKET_ERROR) {
return -1;
}

return receive;
}

void close() {
Expand All @@ -75,12 +105,12 @@ struct UDPSocket::Impl {
};


UDPSocket::UDPSocket(): pimpl_(std::make_unique<Impl>()) {
}
UDPSocket::UDPSocket(int port)
: pimpl_(std::make_unique<Impl>(port)) {}

void UDPSocket::sendTo(const std::string& address, uint16_t port, const std::string& data) {
bool UDPSocket::sendTo(const std::string& address, uint16_t port, const std::string& data) {

pimpl_->sendTo(address, port, data);
return pimpl_->sendTo(address, port, data);
}

int UDPSocket::recvFrom(const std::string& address, uint16_t port, std::vector<unsigned char>& buffer) {
Expand All @@ -89,4 +119,8 @@ int UDPSocket::recvFrom(const std::string& address, uint16_t port, std::vector<u
}

void UDPSocket::close() {
}

pimpl_->close();
}

UDPSocket::~UDPSocket() = default;
8 changes: 6 additions & 2 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@

add_executable(test_socketlib test_socketlib.cpp)
target_link_libraries(test_socketlib PRIVATE simple_socket Catch2::Catch2WithMain)
add_executable(test_tcp test_tcp.cpp)
target_link_libraries(test_tcp PRIVATE simple_socket Catch2::Catch2WithMain)


add_executable(test_udp test_udp.cpp)
target_link_libraries(test_udp PRIVATE simple_socket Catch2::Catch2WithMain)

add_subdirectory(integration)
12 changes: 6 additions & 6 deletions tests/integration/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@

add_executable(run_server run_server.cpp)
target_link_libraries(run_server PRIVATE simple_socket)
add_executable(run_tcp_server run_tcp_server.cpp)
target_link_libraries(run_tcp_server PRIVATE simple_socket)

add_executable(run_client run_client.cpp)
target_link_libraries(run_client PRIVATE simple_socket)
add_executable(run_tcp_client run_tcp_client.cpp)
target_link_libraries(run_tcp_client PRIVATE simple_socket)

if (UNIX)
target_link_libraries(run_server PRIVATE pthread)
target_link_libraries(run_client PRIVATE pthread)
target_link_libraries(run_tcp_server PRIVATE pthread)
target_link_libraries(run_tcp_client PRIVATE pthread)
endif ()
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@

#include "Socket.hpp"
#include "TCPSocket.hpp"

#include <iostream>
#include <vector>

int main() {

ClientSocket client;
TCPClient client;
if (client.connect("127.0.0.1", 8080)) {

std::string message = "Per";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#include "Socket.hpp"
#include "TCPSocket.hpp"

#include <atomic>
#include <iostream>
Expand All @@ -17,7 +17,7 @@ void socketHandler(std::unique_ptr<Connection> conn) {

int main() {

ServerSocket server;
TCPServer server;
server.bind(8080);
server.listen();

Expand Down
Loading

0 comments on commit 0c1a9f4

Please sign in to comment.